在了解Java传参数是pass by value或是pass by reference之前,先了解=
赋值的用法会对理解传参很有帮助
-
赋值(=)的用法
-
=
的意义是赋值,但是这个赋值用在 基本类型 和 对象类型 上会有非常大的差别-
如果
=
用在基本类型上,因为基本类型储存了实际的数值,所以在为其赋值时,是直接将值複製一份新的过去-
因此假设a、b都是基本类型,如果执行了
a=b
,那麽就是将b的内容直接複製一份新的给a,之后如果改变了a的值,也不会影响到b -
此处的基本类型,泛指 int、long、boolean....和其包装型态 Integer、Long、Boolean....,只要是这些类型的变量,都适用基本类型的
=
规则
-
-
但如果
=
用在对象类型上,因为在使用对象操作时,实际储存的其实是对象的引用,所以在为其赋值时,实际上只是把 "引用" 从一个地方複製到另一个地方-
因此假设c、d都是对象类型,如果执行了
c=d
,那麽c和d都会指向原本只有d指向的那个对象,而原本c的那个对象因为没人引用了,所以会被垃圾回收清理掉
-
-
-
具体实例
-
t1、t2是基本类型的
=
效果,t3、t4是对象类型的=
效果
class Tank { int level; } public class Main { public static void main(String[] args) throws InterruptedException { Tank t1 = new Tank(); Tank t2 = new Tank(); t1.level = 1; t2.level = 2; System.out.println("t1: " + t1.level + ", t2: " + t2.level); t1.level = t2.level; //此处只是基本类型的赋值,所以t1、t2仍旧指到两个不同对象 System.out.println("t1: " + t1.level + ", t2: " + t2.level); t1.level = 100; System.out.println("t1: " + t1.level + ", t2: " + t2.level); System.out.println("----"); Tank t3 = new Tank(); Tank t4 = new Tank(); t3.level = 3; t4.level = 4; System.out.println("t3: " + t3.level + ", t4: " + t4.level); //此处是对象类型的赋值,所以是t3和t4都指到了同一个对象上 //而原本t3那个对象因为没人引用了,所以会被垃圾回收清理掉 t3 = t4; System.out.println("t3: " + t3.level + ", t4: " + t4.level); t3.level = 100; System.out.println("t3: " + t3.level + ", t4: " + t4.level); } }
t1: 1, t2: 2 t1: 2, t2: 2 t1: 100, t2: 2 ---- t3: 3, t4: 4 t3: 4, t4: 4 t3: 100, t4: 100
-
-
-
pass by value 和 pass by reference
-
和
=
一样,只要掌握好基本类型实际储存的是"值",而对象类型储存的是"引用",就能了解到底是pass by value还是pass by reference-
基本类型 pass by value,对象类型 pass by reference
class Tank { int level; } public class Main { public static void main(String[] args) throws InterruptedException { Tank t1 = new Tank(); Tank t2 = new Tank(); t1.level = 1; System.out.println("t1.level: " + t1.level); fooInt(t1.level); //基本类型pass by value System.out.println("t1.level: " + t1.level); t2.level = 2; System.out.println("t2.level: " + t2.level); fooTank(t2); //对象类型pass by reference System.out.println("t2.level: " + t2.level); } public static void fooTank(Tank tank){ tank.level = 1000; } public static void fooInt(int level){ level = 5; } }
t1.level: 1 t1.level: 1 t2.level: 2 t2.level: 1000
-
基本类型的List、Set、Map 也是pass by value,对象类型的List、Set、Map是pass by reference
class Tank { int level; } public class Main { public static void main(String[] args) throws InterruptedException { List<Tank> tankList = new ArrayList<>(); List<Integer> intList = new ArrayList<>(); for (int i = 1; i <= 2; i++) { Tank tank = new Tank(); tank.level = i; tankList.add(tank); intList.add(i * 100); } System.out.println("intList: " + intList.get(0) + ", " + intList.get(1)); fooIntList(intList); System.out.println("intList: " + intList.get(0) + ", " + intList.get(1)); System.out.println("tankList: " + tankList.get(0).level + ", " + tankList.get(1).level); fooTankList(tankList); System.out.println("tankList: " + tankList.get(0).level + ", " + tankList.get(1).level); } public static void fooTankList(List<Tank> tankList) { for (Tank tank : tankList) { tank.level = 500; } } public static void fooIntList(List<Integer> intList) { for (Integer i : intList) { i = 2000; } } }
intList: 100, 200 intList: 100, 200 tankList: 1, 2 tankList: 500, 500
-
-