Java - 传参到底是哪种? pass by value or pass by reference

在了解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

猜你喜欢

转载自blog.csdn.net/weixin_40341116/article/details/82593388
今日推荐