java中函数是值传递还是引用传递

2018-10-10  本文已影响0人  HungerDeng

1. 参数为基础数据类型时

    public static void main(String[] args) {
        int a=5;
        changeA(a);
        System.out.println("after changeB a: "+a);
        System.out.println("----------------------");

        Integer b=new Integer(5);
        changeB(b);
        System.out.println("after changeB b: "+b);
    }

    static void changeA(int a){
        a=100;
        System.out.println("in changeA a: "+a);
    }

    static void changeB(Integer b){
        b=100;
        System.out.println("in changeB b: "+b);
    }

//log
in changeA a: 100
after changeB a: 5
----------------------
in changeB b: 100
after changeB b: 5

函数参数相当于函数内部局部变量,当参数为基础数据类型时,为内部局部变量赋值,所以内外变量本质上并不是同一个变量,只是数值相同。

2. 参数为对象类型时

/**
 * 功能:验证Java中函数是值传递还是引用传递
 */
public class ParameterPassingText {

    static class Cat {

        public String name;
        public Cat(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return super.toString() + name;
        }
    }

    public static void main(String[] args) {
        Cat cat = new Cat("白猫");
        System.out.println("before change0: "+cat.toString());
        change0(cat);
        System.out.println("after change0: "+cat.toString());

        System.out.println("======================================================================");

        cat = new Cat("白猫");
        System.out.println("before change1: "+cat.toString());
        change1(cat);
        System.out.println("after change1: "+cat.toString());
    }

    private static void change0(Cat cat) {
        cat.name = "黑猫";
        System.out.println("on change0: "+cat.toString());
    }
    
    private static void change1(Cat cat) {
        cat=new Cat("黑猫");
        System.out.println("on change1: "+cat.toString());
    }
}

打印的Log如下:

before change0: base_knowledge.ParameterPassingText$Cat@7ea987ac白猫
on change0: base_knowledge.ParameterPassingText$Cat@7ea987ac黑猫
after change0: base_knowledge.ParameterPassingText$Cat@7ea987ac黑猫
======================================================================
before change1: base_knowledge.ParameterPassingText$Cat@12a3a380白猫
on change1: base_knowledge.ParameterPassingText$Cat@29453f44黑猫
after change1: base_knowledge.ParameterPassingText$Cat@12a3a380白猫

其实,函数的参数相当于函数内部的局部变量

2.1 change0分析

change0分析
外部引用cat指向地址为7ea987ac的对象。当把外部cat作为参数传入change0时,外部cat指向的地址会被赋值给函数的局部引用cat,所以内外两个cat指向同一地址,即同一对象。change0内改变内部cat的属性本质上也是改变地址为7ea987ac的Cat对象的属性,所以会影响外部cat的属性。

2.2 change1分析

change1分析

把外部cat作为参数传入change1时,主要分成两个步骤:

  1. 外部cat指向的地址会被赋值给函数的局部引用cat
  2. 局部引用cat重新赋值,指向地址为29453f44的另一个Cat对象

所以,在change1内部局部引用cat指向的对象和外部cat并不指向同一对象

综上所述,可以总结为:

  1. 函数的参数相当于函数内部的局部变量
  2. 引用参数传递时,会先把 外部引用指向的地址 赋值给 函数内部的局部变量指向的地址,即外部传值给这个参数实际上就是改变这个参数所指向的内存地址
上一篇 下一篇

猜你喜欢

热点阅读