按值传递: 传递的是值的传递,传递之后互不相关


public class Test2 {  
	private void test1(int a){
		a =5; 
		System.out.println("test1方法中a="+a);
	}
	public static void main(String[] args) {
		Test2 t = new Test2();
		int a = 3;
		t.test1(a);
		System.out.println("main方法中a="+a);
	}
}

运行结果:

test1方法中a=5

main 方法中 a = 3

按引用传递:

指的是在方法调用时,传递的参数是按照引用进行传递,其实传递的引用的地址,就是变量所对应的内存空间的地址。


class Instance{
	public int num = 0 ;
}
public class Test2 {  
	public void dothis(Instance p1){
		p1.num = 20;//4
		System.out.println("dothis中num的值是"+p1.num);
	}
	public static void main(String[] args) {
		Instance p = new Instance();//1
		p.num = 10;//2
		Test2 t = new Test2();
		t.dothis(p);//3
		System.out.println("main中num的值是"+p.num);
	}
}

运行结果:


dothis中num的值是20
main中num的值是20

理解按引用传递 过程中的内存分配,根据上面的例子来说

1. 第一步:创建instance实例对象,并有引用  p -> instance 实例(此时num=0),p存储实例变量的地址

2. 第二步: 修改instance实例对象中num的值,此时有 p - > instance实例(num=10)

3. 第三步:将引用p,作为参数调用dothis方法,注意 引用 p 和方法参数p1,不是同一个变量,但是存储的

instance实例的地址是相同的,就是两变量都是指向同一个实例对象:  p->instance实例(num=10), p1->instance实例(num=10)

4. 第四步:dothis方法中,p1修改指向实例的num,有 p1->instance (num=20)

可以看出来,p 和 p1都是指向同一个实例,于是 main中 p.num的值也是20


如果希望按引用传递的时候,不相互影响呢,拿上面的例子来说,只要dothis方法中,将引用指向一个新创建的

对象就行了。

class Instance{
	public int num = 0 ;
}
public class Test2 {  
	public void dothis(Instance p){
		p = new Instance();
		p.num = 20;//4
		System.out.println("dothis中num的值是"+p.num);
	}
	public static void main(String[] args) {
		Instance p = new Instance();//1
		p.num = 10;//2
		Test2 t = new Test2();
		t.dothis(p);//3
		System.out.println("main中num的值是"+p.num);
	}
}

再次分析,程序过程中发生的引用传递:

3,前面两步和上面相同,第三步,同样 有 变量p 和 形参 p1 的值相同,存放的都是instance 实例的地址

此时两个引用指向的都是同一个变量

4. 第四步,dothis方法中, 形参p1指向的是新创建的instance ,p1中存放的是新的对象的内存地址,

main中 变量p 存放的还是原来的 instance 实例地址,这样,输出的结果就是:

dothis 中 num的值是 20 ,main中num的值是 10

结论:

“在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。

在java里面只有基本类型和按照下面方式定义的String是按值传递,其他的都是按照引用传递(集合和数组也是按照引用传递)。按双引号定义的string 是按值传递  String str =  "hello world";String[] 也是按引用传递