今天在看廖雪峰教程的时候,讲到了参数绑定,也是查了很多资料后理解了,这篇文章就是记录一下 java 中参数绑定的坑点。
基本类型参数的传递
public class Main {public static void main(String[] args) {Person p = new Person();int n = 15; // n的值为15p.setAge(n); // 传入n的值System.out.println(p.getAge()); // 15n = 20; // n的值改为20System.out.println(p.getAge()); // 15}}class Person {private int age;public int getAge() {return this.age;}public void setAge(int age) {this.age = age;}}
从结果可知,修改外部的局部变量n,不影响实例p的age字段,原因是setAge()方法获得的参数,复制了n的值,因此,p.age和局部变量n互不影响。
结论:基本类型参数的传递,是调用方值的复制。双方各自的后续修改,互不影响。
引用类型参数绑定
public class Main {public static void main(String[] args) {Person p = new Person();String[] fullname = new String[] { "Homer", "Simpson" };p.setName(fullname); // 传入fullname数组System.out.println(p.getName()); // "Homer Simpson"fullname[0] = "Bart"; // fullname数组的第一个元素修改为"Bart"System.out.println(p.getName()); // "Bart Simpson"}}class Person {private String[] name;public String getName() {return this.name[0] + " " + this.name[1];}public void setName(String[] name) {this.name = name;}}
注意到setName()的参数现在是一个数组。一开始,把fullname数组传进去,然后,修改fullname数组的内容,结果发现,实例p的字段p.name也被修改了!
结论:引用类型参数的传递,调用方的变量,和接收方的参数变量,指向的是同一个对象。双方任意一方对这个对象的修改,都会影响对方(因为指向同一个对象嘛)。
特例:String
public class Main {public static void main(String[] args) {Person p = new Person();String bob = "Bob";p.setName(bob); // 传入bob变量System.out.println(p.getName()); // "Bob"bob = "Alice"; // bob改名为AliceSystem.out.println(p.getName()); // "Bob"}}class Person {private String name;public String getName() {return this.name;}public void setName(String name) {this.name = name;}}
这里第二次还是输出“Bob”。
首先这里引用参数绑定的机制是没有问题的。正常来说,第二次应该输出“Alice”,但是他却输出了“Bob”。是因为String类型的问题。因为String是不可变的(看源码会发现String类是被final修饰的)
所以,第七行代码这里修改变量bob,实际上是bob的指向更新了,指向了“Alice”。而原来的内存还是没有变,还是“Bob”,而且p.name指向的还是“Bob”(因为bob是重新new了一个示例,与p.name没有关系)
