概念
值传递
在调用方法时会将实际参数的数据复制一份(相当于一个副本),然后传递到方法中,如果在方法中对参数进行修改,不会影响到实际参数。
引用传递
调用方法时将实际参数的地址传递到方法中,那么在方法中对参数进行修改,将影响到实际参数
(引用传递的本质是传递内存空间地址,而非值本身)
值传递和引用传递的区别
根本区别在于值传递会创建副本,而引用传递不创建副本;
值传递在方法中无法改变实际参数,而引用传递可以改变原始对象
值传递示例
//值传递
public class ValueDemo{
public static void main(String[] args){
int x = 10;
method(x);
System.out.println("x="+x);
}
public static void method(int mx){
mx=20;
}
}//x=10
把10复制了一份交给了mx,在栈内存中变为20的是mx(也可以说是x的副本),实际x的值还是10
打印结果为:
引用传递示例一
引用传递的本质是传递内存空间地址,而非值本身
public class RefDemo {
public static void main(String[] args){
Chicken c = new Chicken();
method(c);
System.out.println("Chicken age="+c.age);
}
public static void method(Chicken chicken){
chicken.age=5;
}
}
class Chicken{
int age=2;
}
可以理解为一个对象有两个引用,c和chicken指向的内存都是age=2,当执行到chicken.age=5时,堆内存里变成了age=5,所有c.age也变成了5(二者操作的是同一块内存空间)
打印结果为:
引用传递示例二:String传递
字符串本身就是一个对象,每一个对象都是一个内存地址
public StringDemo{
public static void main(String[] args){
String name = "唱,跳,rap,篮球";
method(name);
System.out.println("name="+name);
//打印结果为唱,跳,rap,篮球
}
public static void method(String sname){
sname = "哎哟,你干嘛~";
}
}
字符串本身就是一个对象,每一个对象都是一个内存地址,一个字符串出现就是一个对象,所以“哎哟,你干嘛~”在堆内存中会新开辟一块内存,本来name和sname都是指向“唱,跳,rap,篮球”,但执行sname=“哎哟,你干嘛~”后,sname的指向了新的字符串对象,所以name的打印结果没有改变。
引用传递示例三
public class RefDemo3{
public static void main(String[] args){
Person p = new Person();
method(p);
System.out.println("person name="+p.name);
//person name=tom
}
public static void method(Person p){
p.name = "tom";
}
}
class Person{
String name = "jerry";
}
p,p1在栈内存中的内存地址都指向堆内存中的name,而name中存的不是具体值,而是指向字符串"jerry"的地址(字符串本身就是一个对象,每一个对象都是一个内存地址),所以当我们让name="tom"时,实际上是把name指向“jerry”改为了指向"tom"。