java中的值传递与引用传递(java中只有值传递,没有引用传递)

Java和Javascript中的值传递与引用传递 

String类型与StringBuffer类型的转换

Java中字符数组、String类、StringBuffer三者之间相互转换

值传递(实参的值被拷贝了一份传递给形参)

引用传递(实参的内存地址被拷贝了一份传递给形参)

问题:java中只有值传递,没有引用传递

什么叫值传递,值传递就是把自己拷贝一份,并把拷贝后的那一份传递给别人(注意:值传递的重点和特点就是拷贝)。

不管是值传递还是引用传递,都是被拷贝了一份,只不过,值传递拷贝的是值,而引用传递拷贝的是内存地址,而值传递的重点和特点就是拷贝,所以从拷贝的角度来讲,值传递和引用传递这两者都需要拷贝,所以说,java中只有值传递

但是,从传递的内容来看,值传递,传递的是拷贝的,而引用传递,传递的是拷贝的内存地址所以说,java中有值传递和引用传递所以就要看你们从哪个角度上讲了!

案例1

String s1 = "江西省赣州市于都县";
		String s2 = s1;
		System.out.println(s1 + "," + s1.hashCode() + "," + System.identityHashCode(s1));
		System.out.println(s2 + "," + s2.hashCode() + "," + System.identityHashCode(s2));
		s2 = "于都县"; //s2指向了新的空间地址
		System.out.println(s1 + "," + s1.hashCode() + "," + System.identityHashCode(s1));
		System.out.println(s2 + "," + s2.hashCode() + "," + System.identityHashCode(s2));

案例2:值传递

//交换2个变量的值
	public void swapValue(int num1, int num2) {
		System.out.println("交换前,形参num1=" + num1 + ",形参num2=" + num2);
		int temp;
		temp = num1;
		num1 = num2;
		num2 = temp;
		System.out.println("交换后,形参num1=" + num1 + ",形参num2=" + num2);
	}

public static void main(String[] args) {
		System.out.println("*********************************");
		User user = new User();
		int x = 5, y =10;
		System.out.println("调用swapValue函数前,实参x=" + x + ",实参y=" + y);
//值传递(参数是基本类型(byte,short,int,long,float,double,char,boolean),传递的是基本类型的字面量值的拷贝。)
		user.swapValue(x, y);
		System.out.println("调用swapValue函数后,实参x=" + x + ",实参y=" + y);
	}

案例3:引用传递

public static void main(String[] args) {
		User user = new User();
		//引用传递(参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。)
		StringBuffer stra = new StringBuffer ("1");
		System.out.println (stra);
		user.changeStr(stra);
		System.out.println (stra);//1,yes 引用类型因为是传递地址,因此修改了堆内存的同一对象
	}
	
	public void changeStr(StringBuffer stringBuffer){
		stringBuffer.append (",yes");
	}

案例4:引用传递(在函数中,给形参重新赋值)

public static void main(String[] args) {
		User user = new User();
		//
		StringBuffer stra = new StringBuffer ("江西省赣州市于都县");
		System.out.println ("实参stra=" + stra);//实参stra=江西省赣州市于都县
		user.changeStr(stra);
		System.out.println ("实参stra=" + stra);//实参stra=江西省赣州市于都县
	}
	
	public void changeStr(StringBuffer stringBuffer){
//new StringBuffer("hello")这句话让stringBuffer指向了新的地址空间
		stringBuffer = new StringBuffer("hello");//此时形参和实参已经分道扬镳了
		stringBuffer.append("world");
		//形参stringBuffer=hello
		System.out.println("形参stringBuffer=" + stringBuffer);
	}

案例5:引用传递的特殊情况(String类型)

如上:原先形参str与实参s指向同一片堆内存区域,之后str="20"将str的内存指向另一块堆内存导致结果的特殊。

public static void main(String[] args) {
		User user = new User();
		//
		String s = "10"; //实参s的值为10
		System.out.println ("实参s=" + s + "," + System.identityHashCode(s));//实参s
		user.changeString(s);
		//String是引用类型,传递的是地址,但是并未发生改变		
		System.out.println ("实参s=" + s + "," + System.identityHashCode(s));//实参s
	}
	
	public void changeString(String str){
		System.out.println("形参str=" + str + "," + System.identityHashCode(str));
		str = "20";
//		str = "10"; //大家可以解除注释,测试运行这行代码(这里把形参str的值设置成和实参s的值一样时,形参和实参的地址是一样的)
		System.out.println("形参str=" + str + "," + System.identityHashCode(str));
	}

System.identityHashCode(str)这句代码,可以理解成获取str这个对象的内存地址。

猜你喜欢

转载自blog.csdn.net/czh500/article/details/114599531