自己一直没有完全搞明白java的传值,传引用,传对象的区别,有时候觉得自己搞懂了,一碰到具体例子,又懵了,所以今天来敲代码看一下。
第一版:
public static void main(String[] args) { List<Integer> userListA=new ArrayList<>(); userListA.add(1); List<Integer> userListB=new ArrayList<>(); userListB=userListA; System.out.println(userListA == userListB); }
来看下结果:
true
所以这种直接=的情况,两个list其实指向的是堆内的同一个对象。
第二版:
public static void main(String[] args) { List<Integer> userListA=new ArrayList<>(); userListA.add(1); List<Integer> userListB=new ArrayList<>(); userListB.add(1); System.out.println(userListA == userListB); }
答案是:
false
当分别赋值,此时两个list指向不同。
这里有个有趣的地方,此时如果我们不比较list,而是比较list中的第一个对象,你会发现,返回结果也是true。
当我们继续将放到list中的值增大,一直到128,如下:
public static void main(String[] args) { List<Integer> userListA=new ArrayList<>(); userListA.add(128); List<Integer> userListB=new ArrayList<>(); userListB.add(128); System.out.println(userListA.get(0) == userListB.get(0)); }
此时结果就会变为 false,这种情况,是因为常量池的存在。
Byte, Short, Integer, Long, Character, Boolean, Float, Double, 除Float和Double以外, 其它六种都有常量池,,只在大于等于-128并且小于等于127时使用常量池
第三版:
此时我们不往list中放数字,放个对象试试:
public static void main(String[] args) { User user=new User(); user.setAge(1); user.setName("蝈蝈"); List<User> userListA=new ArrayList<>(); userListA.add(user); List<User> userListB=null; userListB=userListA; System.out.println(userListA == userListB); }
结果当然是:
true
第四版:
看看这个:
public static void main(String[] args) { User user=new User(); user.setAge(1); user.setName("蝈蝈"); List<User> userListA=new ArrayList<>(); userListA.add(user); List<User> userListB=new ArrayList<>(); userListB.add(user); System.out.println(userListA == userListB); System.out.println(userListA.get(0)==userListB.get(0)); }
结果为:
false true
第五版:
到现在为止还是挺清晰的,那么addAll的情况如何呢?
public static void main(String[] args) { User user=new User(); user.setAge(1); user.setName("蝈蝈"); List<User> userListA=new ArrayList<>(); userListA.add(user); List<User> userListB=new ArrayList<>(); userListB.addAll(userListA); System.out.println(userListA == userListB); System.out.println(userListA.get(0)==userListB.get(0)); }
结果:
false true
总结
其实java中,只有一种参数传递,就是值传递,当一个对象是基本数据类型对象时,把它当作参数传递给另一个方法,此时传递的是值,也就是会讲值拷贝给另一个方法。基本类型数据在方法里被修改了,原来的调用方那里是不会变的,因为是被复制了一份的,不会影响到原来的值;
当一个对象是个对象引用类型,比如User对象时,把它当作参数传递给另一个方法,此时传递的也是值,只不过此时,值并非某个数字,而是堆内存的地址。