Java 基础教程

Java 面向对象

Java 高级教程

Java 笔记

java 调用方法时,参数传递的是引用还是值

Java 对象和类 Java 对象和类


针对如上问题,先说结论,java 调用方法时,参数传递的是值。也就是说,方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。有很多初学者看到一些资料中提到“方法传递对象时,传递的是对象的引用(pass-by-reference)”,这让他们又很混乱,其实对象传递的是复制引用对象的值,也可以理解为存放引用原始对象引用的指针值,如果你觉得比较难理解,看下面的图解。

方法传递对象类型

public class NationDemo {

    public static void main(String[] args) {

        Nation usa = new Nation("usa");
        Nation america = usa;

        // we pass the object to foo
        foo(usa);

        // usa variable is still pointing to the "usa" when foo(...) returns
        System.out.println(usa.getName().equals("usa")); // true
        System.out.println(usa.getName().equals("china")); // false
        System.out.println(usa == america); // true
    }

    public static void foo(Nation nation) {
        System.out.println(nation.getName().equals("usa")); // true
        // change nation inside of foo() to point to a new Nation instance "china"
        nation = new Nation("china");
        System.out.println(nation.getName().equals("china")); // true
    }

    static class Nation {
        private String name;
        public Nation(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
}

上图直观解释了方法传递对象时,传递的是存放对象地址的值,传递的参数 nation 为复制 usa 变量存放的指向 Nation(0x1234) 的对象,后在方法中存放的地址变为另一个对象 Nation(0x5678),方法调用结束后,usa 变量引用的对象内容没有任何变动。从图上也可以看出,变量参数都是存放在栈(stack)空间(属于私有线程栈),类实例即对象是存放在堆(heap)空间上的(共享空间)。

方法传递基本类型

public class CallByPrimitiveTypeValueDemo {

    public static void main(String[] args) {
        boolean bool = true;
        char c = 'a';
        byte b = 1;
        short s = 11;
        int i = 101;
        long l = 1001L;
        float f = 10001f;
        double d = 100001d;
        bar(bool, c, b, s, i, l, f, d);
        System.out.println(bool);
        System.out.println(c);
        System.out.println(b);
        System.out.println(s);
        System.out.println(i);
        System.out.println(l);
        System.out.println(f);
        System.out.println(d);
    }

    public static void bar(boolean bool, char c, byte b, short s, int i, long l, float f, double d) {
        bool = false;
        c = 'b';
        b = 2;
        s = 12;
        i = 102;
        l = 1002L;
        f = 10002f;
        d = 100002d;
    }
}

方法传递基本类型比对象参数更好理解,方法中传递的是基本类型的值,且都发生在栈空间内。