别再被面试官问倒了!Java 参数传递的底层逻辑,看完秒懂

27 阅读2分钟

上节课我们讲解了 Java 中 String 的相关特性,现在公布上节思考题的答案:

String s1 = "ab";
//两个字符串字面量的拼接,编译器会直接优化为 "ab",
String s2 = "a" + "b"; 
System.out.println(s1 == s2); // true

String a = "a";
String s2 = a + "b"; // 运行时通过StringBuilder拼接,是一个新对象
System.out.println(s1 == s2); // false

一、参数传递方式

在 Java 中,参数传递的方式是“按值传递” 。这意味着:

  • 对于基本数据类型(如 intdoubleboolean 等),传递的是该值的一个副本
  • 对于引用类型(如对象、数组等),传递的是引用的副本(对象在堆内存中引用的副本),而不是对象本身。

1. 基本数据类型的参数传递

public static void changeValue(int x) {
    x = 100;
}

public static void main(String[] args) {
    int a = 10;
    changeValue(a);
    System.out.println(a); // 输出:10
}

说明:方法中修改的是 a 的副本x,不影响原始变量 a

2. 引用类型的参数传递

引用类型传递的是引用的副本。

public static void changeObject(Person p) {
    p.setName("Alice"); // 引用副本和原始对象指向同一个地址
    p = new Person("Bob");    // 重新赋值副本的引用(不影响原对象)
}

public static void main(String[] args) {
    Person person = new Person("Tom");
    changeObject(person);
    System.out.println(person.getName()); // 输出:Alice
}

说明:

  • 因为 p 和 person 指向同一个地址,所以p.setName("Alice") 修改了原对象的内容。
  • p = new Person("Bob") 只是改变了局部变量 p 的指向,不会影响 person

二、总结

类型传递内容能否修改原始值/对象内容
基本类型值的副本不能
引用类型引用(地址)的副本能修改对象内容 不能改变原始引用指向

三、思考题

下边的代码输出什么?评论区说出你的答案。

public class ParamTest {
    public static void main(String[] args) {
        String str = "Hello";
        change(str);
        System.out.println("main 方法中 str = " + str);

        StringBuilder sb = new StringBuilder("Hello");
        change(sb);
        System.out.println("main 方法中 sb = " + sb);
    }

    public static void change(String s) {
        s = "World";
    }

    public static void change(StringBuilder sb) {
        sb.append(" World");
    }
}