Java中参数传递的方式

结论

Java 中只存在值传递

值传递

public class PassByValue {
    
    public static void main(String[] args) {
        int mainNum = 1;
        passByValue(mainNum);
        System.out.println(String.format("mainNum: %d", mainNum));
    }

    public static void passByValue(int num) {
        num = 2;
        System.out.println(String.format("num: %d", num));
    }
    
}

结果:

num: 2
mainNum: 1

引用传递

public class PassByReference {

    static class Person {
        public Person(String name) {
            this.name = name;
        }

        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    public static void main(String[] args) {
        Person person = new Person("rmrf2020");
        passByReference(person);
        System.out.println(String.format("personName: %s", person.getName()));
    }

    public static void passByReference(Person person) {
        person.setName("I changed my Name");
        System.out.println(String.format("changedPersonName: %s", person.getName()));
    }
    
}

结果:

changedPersonName: I changed my Name
personName: I changed my Name

引用传递 or 值传递

上面两个例子,将引用传递和值传递的特性都表现出来了,可能有人会说:”基本类型用的是值传递,对象使用引用传递“。这样想的朋友可以看一下下面这个例子,这个例子我就不贴结果了,自己试一下才会记忆深刻

public class StringPassType {
    
    public static void main(String[] args) {
        String s = "s";
        stringPassType(s);
        System.out.println(String.format("personName: %s", s));
    }

    public static void stringPassType(String changedS) {
        changedS = "I was changed!";
        System.out.println(String.format("personName: %s", changedS));
    }
    
}

上面这个例子看完了,发现传递对象类型也是“值传递”,显然不符合推测的“基本类型用的是值传递,对象使用引用传递”。

实际上在 Java 中只有值传递。
在 Java 中,String 类是不可变对象,因为它的修饰符是final,既然上面这个例子的结果changeSs输出内容不一致,那么它们的地址肯定也不一致。
实际上s传递的是"s"的地址,changedS指向的也是"s"的地址,当changedS = "I was changed!";语句执行时,只是将changedS指向"I was changed!"的地址,而s指向的内存地址是没有改变的。

在 IDEA 上也能看出一下差别

image-20220120112505565

IDEA会提示我们将changedS修改为本地变量,因为它是否是传递过来的其实没有任何影响。

结合 @Hollis 的图理解,效果更佳。

v2-43a9da74c477ac45106eafc29becb422_r.jpg