java所有参数都是值传递:基本类型传数值副本,引用类型传地址副本;修改引用类型对象内容会影响原对象,但重新赋值引用变量不会影响原变量。

Java里没有真正的“引用传递”,所有参数都是值传递——但基本类型传的是数值本身,引用类型传的是地址的副本。区分关键不在“传什么”,而在“改什么”是否影响原变量。
看变量存的是什么
基本类型(int、boolean、char、double等)变量里直接放数据,比如 int a = 5,栈中就存着数字 5。
引用类型(String、ArrayList、自定义类、数组等)变量里存的是一个内存地址,比如 String s = "hello",栈中存的不是"hello",而是指向堆里那个字符串对象的一串地址(如 0x7a1f)。
看赋值或传参时复制了什么
赋值或作为参数传入方法时:
- 基本类型:复制数值 ——
int b = a,b 得到的是 5 的一份新拷贝,改 b 不影响 a - 引用类型:复制地址 ——
String t = s,t 得到的是 0x7a1f 的一份新拷贝,s 和 t 指向堆中同一个对象
看修改行为是否波及原对象
这是最实用的判断方式:
- 对基本类型参数重新赋值(如
x = 20),只改形参副本,原变量不变 - 对引用类型参数调用方法或修改属性(如
list.add("x")或obj.name = "new"),因地址副本仍指向原对象,所以原对象内容被改 - 但若在方法内让引用变量指向新对象(如
arr = new int[5]或s = "world"),只是把地址副本换了个指向,原变量仍指向旧对象,不受影响
记一个典型对比例子
下面两段代码能直观体现差异:
基本类型:int n = 3; modify(n); System.out.println(n); // 输出还是 3(modify 内改 n 不影响外边)
引用类型:int[] arr = {1}; modify(arr); System.out.println(arr[0]); // 输出可能是 99(modify 内写 arr[0] = 99 就会生效)
但若 modify 内写 arr = new int[]{8,8,8},外面的 arr[0] 仍是 1 —— 因为只是换了副本的指向。










