java值传递和引用传递的区别?举例一些常见都笔试面试题说明,最后有速记口诀

java值传递和引用传递的区别?举例一些常见都笔试面试题说明,最后有速记口诀

先说结论:

Java 里只有值传递,没有真正的引用传递。

很多人会混淆,是因为:

  • 基本类型传的是"值的副本"
  • 对象传的是"引用的副本"

注意:对象传的是引用的副本,不是引用传递。


1. 值传递和引用传递到底区别是什么

值传递 :把实参的值复制一份给形参。

方法里改形参,不会直接改掉调用者手里的那个变量。

引用传递 :把"变量本身"交给方法。

方法里如果改了这个引用绑定的对象,甚至让它指向别处,调用者也会跟着变。

Java 没有这种"真正的引用传递"。


2. Java 里到底怎么传

基本类型

例如 intdoublechar

传的是数值副本。

java 复制代码
public class Demo {
    public static void add(int x) {
        x++;
    }

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

原因:add 里拿到的是 a 的副本 x,改的是 x,不是 a


引用类型

例如 String、数组、普通对象

传的是"引用的副本"。

java 复制代码
class Person {
    String name;
}

public class Demo {
    public static void change(Person p) {
        p.name = "Alice";
    }

    public static void main(String[] args) {
        Person p = new Person();
        p.name = "Bob";
        change(p);
        System.out.println(p.name); // Alice
    }
}

这里为什么变了?

  • p 里存的是对象地址
  • 调用方法时,把这个地址复制一份给了形参
  • 两个引用都指向同一个对象
  • 所以改对象内部状态,外面能看到

但这依然是值传递,因为传过去的是"地址这个值"的副本。


3. 最容易考的面试陷阱

题1:基本类型一定改不动

java 复制代码
public static void change(int x) {
    x = 100;
}

public static void main(String[] args) {
    int a = 10;
    change(a);
    System.out.println(a);
}

结果:10


题2:改对象属性,外面能看到

java 复制代码
class Student {
    int age;
}

public static void change(Student s) {
    s.age = 20;
}

public static void main(String[] args) {
    Student s = new Student();
    s.age = 10;
    change(s);
    System.out.println(s.age);
}

结果:20


题3:方法里把参数指向新对象,外面不变

java 复制代码
class Student {
    int age;
}

public static void change(Student s) {
    s = new Student();
    s.age = 20;
}

public static void main(String[] args) {
    Student s = new Student();
    s.age = 10;
    change(s);
    System.out.println(s.age);
}

结果:10

原因:

  • 方法里只是让"形参副本"指向了新对象
  • 外面的 s 还指向原来的对象

这题是面试最爱问的。


题4:String 为什么改不掉

java 复制代码
public static void change(String str) {
    str = str + " world";
}

public static void main(String[] args) {
    String s = "hello";
    change(s);
    System.out.println(s);
}

结果:hello

原因有两层:

  • Java 还是值传递
  • String 不可变,str + " world" 会产生新对象,只改了形参的指向

题5:数组元素能改,但整个数组换掉不行

java 复制代码
public static void change(int[] arr) {
    arr[0] = 99;
}

public static void main(String[] args) {
    int[] a = {1, 2, 3};
    change(a);
    System.out.println(a[0]); // 99
}

能改元素,因为操作的是同一个数组对象。

再看:

java 复制代码
public static void change(int[] arr) {
    arr = new int[]{9, 9, 9};
}

public static void main(String[] args) {
    int[] a = {1, 2, 3};
    change(a);
    System.out.println(a[0]); // 1
}

不能改外面的引用,因为只是改了形参副本。


题6:交换两个值为什么失败

java 复制代码
public static void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

public static void main(String[] args) {
    int x = 1, y = 2;
    swap(x, y);
    System.out.println(x + ", " + y);
}

结果:1, 2

因为交换的是副本,不是原变量。

这题常引出结论:

Java 不能像 C++ 引用参数那样直接交换调用者的两个基本类型变量。


4. 面试里最标准的一句话

如果面试官问:

"Java 是值传递还是引用传递?"

标准答法:

Java 永远是值传递。对于基本类型,传的是值本身;对于对象类型,传的是对象引用的副本。


5. 一张表记住

参数类型 传递内容 方法内修改是否影响外部变量 方法内修改对象内容是否影响外部
基本类型 值的副本 不适用
引用类型 引用的副本

6. 面试高频误区

  • "Java 对象是引用传递"

    错。是引用的值传递

  • "方法里 new 一个对象,外面也会变"

    错。只改了形参指向。

  • "String 传进去后改不了,说明不是引用类型"

    错。String 是引用类型,只是它不可变


7. 最后给你一个背诵版

Java 只有值传递。
基本类型传值副本;引用类型传引用副本。
所以:改对象内容能影响外部,改引用指向不能影响外部。

可以直接背这版。

口诀版

Java 只有值传递,绝无引用传递。
基本类型传数值,对象类型传地址副本。
改值不影响外面,改对象内容可能影响外面。
改引用指向没用,new 了对象也带不出去。
String 看着像能改,其实不可变。
数组、对象看同理:改内部可以,换整体不行。

面试答题模板

如果面试官问"Java 到底是值传递还是引用传递",标准回答直接说:

Java 永远是值传递。基本类型传的是值的副本;引用类型传的是引用的副本。
因此,方法内修改对象的成员变量,外部可能看到变化;但让形参重新指向新对象,外部不会变。

高频判断口诀

  • intdoublechar:改形参,外面不变
  • 对象.属性 = xxx:外面通常会变
  • 形参 = new Xxx():外面不变
  • 形参 = 另一个对象:外面不变
  • arr[0] = ...:外面会变
  • arr = new int[]{...}:外面不变
  • str = str + "x":外面不变

笔试速判四字诀

看你改谁

  • 改"对象里面的东西":可能影响外面
  • 改"形参本身指向":一定不影响外面

最短背诵版

Java 只有值传递。
基本类型传值,对象类型传引用副本。
能改对象内容,不能改外部引用指向。

相关推荐
huabiangaozhi2 小时前
Spring Cloud Gateway 整合Spring Security
java·后端·spring
HLC++2 小时前
C++中的类和对象
开发语言·c++
小王不爱笑1322 小时前
Java List 集合全面解析:ArrayList、LinkedList 与 Vector 的深度对比
java·windows·list
setmoon2142 小时前
C++与量子计算模拟
开发语言·c++·算法
KIKIiiiiiiii2 小时前
微信自动化机器人开发
java·开发语言·人工智能·python·微信·自动化
victory04312 小时前
containerd打包命令 和NFS挂载
java·开发语言
野犬寒鸦2 小时前
从零起步学习计算机操作系统:进程篇(知识扩展提升)
java·服务器·开发语言·后端·面试
※※冰馨※※2 小时前
【QT】System error #1455: 页面文件太小,无法完成操作
开发语言·windows·qt
Amnesia0_02 小时前
C++的异常
开发语言·c++·学习