1、首先弄清楚一个问题:Java有没有指针?
对于在C和C++里头曾经给我们带来欢乐同时也有无限痛苦的指针,很多人宁愿它再也不要出现在Java里头。然而事实上,Java是有指针的,Java中每个对象(除基本数据类型以外)的标识符都属于指针的一种。但它们的使用受到了严格的限制和防范,在<Thinking in Java>一书中称它们为句柄。
2、传递句柄 将句柄传递进入一个方法时,指向的仍然是相同的对象。 public class Testit { private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public static void main(String[] args) { Testit a = new Testit(); a.setName("a"); Testit b = new Testit(); b.setName("b"); System.out.println("before swap: " + "a=" + a + " name: " + a.getName()); swap(a,b); }
private static void swap(Testit swap1, Testit swap2) { System.out.println("swaping: " + "a= " + swap1 + " name: " + swap1.getName()); Testit temp; temp = swap1; swap1 = swap2; swap2 = temp; }
}
输出结果: before swap: a=com.lib.Testit@16930e2 name: a swaping: a= com.lib.Testit@16930e2 name: a
3、一个句柄的传递会使调用者的对象发生意外的改变。 public class Testit { private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public static void main(String[] args) { Testit a = new Testit(); a.setName("a"); Testit b = new Testit(); b.setName("b"); System.out.println("before swap: " + "a=" + a + " name: " + a.getName()); swap(a,b); System.out.println("after swap: " + "a=" + a + " name: " + a.getName()); }
private static void swap(Testit swap1, Testit swap2) { Testit temp; temp = swap1; swap1 = swap2; swap2 = temp; swap1.setName("a's name"); swap2.setName("b's name"); }
}
输出结果: before swap: a=com.lib.Testit@16930e2 name: a after swap: a=com.lib.Testit@16930e2 name: b's name
我们看到,a依旧是原来那个a,但name却不是原来那个name了! 在swap()方法中,swap1和swap2互相换过来了,这个时候swap2指向的是a,所以在setName()的时候改变的是a的name,而不是b的name。
为什么会这样呢? liang_chen兄高见:Java里的传值实际上是拷贝引用,而不是拷贝对象。
总结: 1:对于值类型的参数来说,传递的是值的拷贝. 2:对于引用类型的参数来说,传递的是引用本身的拷贝. 所以关键要看你如何理解传值中的这个“值”了。 |