主要参考来自这两篇:
Java:按值传递还是按引用传递详细解说
Java 到底是值传递还是引用传递? - 知乎
为了方便我自己的理解(每次记了就忘,也是很无奈了==),作了一下整理。
我们先下结论:java的参数传递就是采用按值传递的。再来说明其中道理。首先,基本类型与引用类型的值传递是不同的。
int baseNum = 9;
String str = "java";
对于基本数据类型而言,值就直接保存在变量中,对于引用类型而言,对象变量保存的是值的地址。
赋值运算对于基本类型而言是覆盖原值,对于引用类型而言是更改地址。
baseNum = 20;
str = "python";
当使用函数传递时,基本数据类型传递数值的拷贝,传递后就不相关了。引用类型传递引用地址,如果该引用是可以改变的,那么,传递后在方法中所做的改变在方法外部也奏效。
一、基本类型传递值的拷贝,失去联系,方法内外不影响。
int num = 1;
public void changeNum(int n){
num ++;
System.out.println("in fun:" + num); //num = 2
}
System.out.println(num); //num = 1
二、引用类型传递引用(地址),如果该引用类型没有可以修改自身的方法,那么方法内的修改无效
String str = "yinglish";
public void changeStr(String s){
s = "hello";
System.out.println("in fun:" + s); //s = hello
}
System.out.println(s); //s = yinglish
三、传入的引用类型有修改自身的方法
StringBuilder sb = new StringBuilder("yinglish");
changeName(sb);
System.out.println(sb); //yinglish hello
public static void changeName(StringBuilder n){
n.append(" hello");
}
四、传入的引用类有修改方法,但是函数里面采用的赋值处理,则不能改变原引用。
StringBuilder sb = new StringBuilder("yinglish");
changeName(sb);
System.out.println(sb); //yinglish
public static void changeName(StringBuilder n){
n = new StringBuilder("hello");
}
下面分别为第一、二三和第四个例子的图示:
可以看到,引用传递传递的是引用的地址,我们可以理解为传递地址值,亦即有些人说“一切传引用其实本质上是传值”。