传递的到底是什么?怎么会这样
public class Test{
public static void main(String args[]){
String ac = new String( "abc ") ;
p(ac);
System.out.println(ac);
int[] o = new int[]{1,2,3};
pp(o);
for(int av=0 ;av <o.length;av++)
System.out.println(o[av]);
}
static void p(String t){
t= "vvvvvv ";
}
static void pp(int[] j){
j[0]++;
j[1]++;
j[2]++;
}
}
String不是基本类型,我用一个方法改变了他的值,为什么不能保存下来?而int[]也不是基本类型,但用一个方法就可以改变它的内容呢?
不是说非基本类型传递的是对象的句柄吗?
------解决方案--------------------传递的是值,在java中参数传递是值拷贝。
可以这么理解:
当程序执行到函数pp中时,存在两个引用 ac和 t,其中t是ac的一个拷贝,所以t和ac都指向同一个string对象,当执行语句t=“ttttttt”之后,引用t指向的新的string对象,但是并没有改变ac的指向。
在p函数中,情况类似,但是操作j[i]改变的是数组容器的内容,不是j引用指向的对象。
------解决方案--------------------又来了...
传递的是什么并不重要, 因为从不同的角度理解, 可以解释为传值或者传引用, 但这都是字面上的东西, 实质都是一样的.
你可以在方法内部改变一个对象, 但却不可以使一个引用在方法返回后指向另一个对象
------解决方案--------------------String是不可变的
你 t= " "
根本没有改变传过来的String
如果有
t.setText( " ")就可以改变
但是没有
------解决方案--------------------不是说非基本类型传递的是对象的句柄吗?
----------------------
传递的确实是对象的句柄啊,准确的说传递的是句柄的COPY.
1.但该COPY同样指向该对象,所以你改变了该对象的值,原来句柄指向的对象就发生变化,你这时再打印原来的对象,它已经变化了,就如同你的数组一样.
2.然而,在String的例子中你实际上是改变了COPY的句柄的指向,让它指向了其他的对象,原来句柄的指向没有发生改变,所以打印原对象值也就没有改变.
------解决方案--------------------考虑下这个方法
public class Test{
public static void main(String args[]){
String ac = new String( "abc ") ;
ac=p(ac);
System.out.println(ac);
int[] o = new int[]{1,2,3};
pp(o);
for(int av=0 ;av <o.length;av++)
System.out.println(o[av]);
}
static String p(String t){
t= "vvvvvv ";
return t;
}
static void pp(int[] j){
j[0]++;
j[1]++;
j[2]++;
}
}
------解决方案--------------------void change(Date date) {
date = new Date(102938392);
}
void change(String str) {
str = "abcdefg ";
}
public static void main(String[] args) {
Date date = new Date();
change(date);
String str = "aaaaaa ";
change(str);
}
上面两个change方法本质上是一样的, 都是让引用指向一个新的对象, 当退出方法后, 原来的main方法里面的date和str引用依然指向原来的对象
所以String和其它对象并没有什么区别, 要说区别, 那就是String是不可变类...
这里的关键不是String的特殊性, 而是引用和对象的区别.
在方法里, 你可以改变传递进来的参数所指向的对象, 但你不可以使引用在退出方法后还指向另一个新的对象...