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这个对象的内存地址。