Java中的值传递与“引用传递”

Posted mfmdaoyou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中的值传递与“引用传递”相关的知识,希望对你有一定的参考价值。


首先,Java没有 引用传递 这么一说。

Java仅仅有值传递。传递的都是值,基本数据类型传递的是值。引用类型传递的是地址值。

我来理一下这当中宛如米线跟米面绞在一起了,再跟粉丝混在一起的关系。

好的,我们来看第一个样例:

public static void main(String[] args) {
		int a = 1;
		int b = 4;
		System.out.println("Before : a=" + a + "," + "b=" + b);
		swap(a, b);
		System.out.println("After  : a=" + a + "," + "b=" + b);

	}

	private static void swap(int a, int b) {
		int temp = a;
		a = b;
		b = temp;
	}

结果:

Before : a=1,b=4
After  : a=1,b=4

这没什么好说的,main函数内的a和b 与 swap()函数中的a,b半毛线关系都没有,交换的仅仅是swap函数中的局部变量,并不会影响到main函数中的a和b.

2,第二个:

public static void main(String[] args) {
		Integer a = new Integer(3);
		Integer b = new Integer(4);
		System.out.println("Before : a = " + a + "   b = " + b);
		swap(a, b);
		System.out.println("After  : a = " + a + "   b = " + b);
	}
	public static void swap(Integer a1, Integer b1) {
		Integer temp = a1;
		a1 = b1;
		b1 = temp;
	}



结果:

Before : a = 3   b = 4
After  : a = 3   b = 4

非常多人可能会吃惊。为什么会介个样子的呢?为什么 还是木有交换呢。

1。a将引用值传给a1,b将引用值传给b1,此时a1和a都指向3的空间。b1和b都指向4的空间

2。在swap函数中。a1和b1的引用值发生了交换,注意是引用值

此时a1指向4,b1指向3

3,再看看打印语句:

System.out.println("After  : a = " + a + "   b = " + b);
打印的是a 和 b 的值,跟a1,b1又有什么关系呢?交换的仅仅是a1和b1的引用值,说白了a1,b1就是a,b的引用副本。这里有四个引用指向了2个地址空间。交换了当中的两个。并不影响其它两个引用的值。

好,说完了上面这么多。我们再来看一个样例:

首先自己定义一个类:

public class Person {

	private int age;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	

}


public static void main(String[] args) {
		Person p = new Person();
		System.out.println("Before : "+p.getAge());
		changePersonAge(p);
		System.out.println("After : " + p.getAge());
	}

	public static void changePersonAge(Person p) {
		p.setAge(10);
	}
结果:

Before : 0
After : 10

是不是非常奇妙,这里居然又能够改变值啦。

注意:这里p将引用副本传递给changePersonAge()函数,相同此时存在两个引用指向堆空间中的Person对象。那么在changePersonAge()方法中调用setAge()函数,实质改变的也就是Person对象中age的值,这里改变的是对象,而不是单纯的引用值的传递。



我们再来看一个样例:

public static void main(String[] args) {
		String str = "test";
		System.out.println("Before = "+str);
		changeStr(str);
		System.out.println("After  =  " + str);
	}
	public static void changeStr(String str) {
		str += "haha";
	}

结果:

Before = test
After =  test

哎哟我去,咋又不能改变了呢?

在main方法里str首先指向常量池中的“test”,而后将引用副本传递给changeStr方法中的str。相同这里存在两个引用,可是在changeStr方法里做出了,str+="haha";的操作。注意。此时changeStr中的str不再指向“test”,而是指向了“testhaha”,两个引用指向了不同的空间,打印出来当然没有改变值咯。



最后。我们再来看一个小样例,稳固一下。

public static void main(String[] args) {
		StringBuffer sb = new StringBuffer("test2");
		System.out.println("Before   = " + sb);
		changeStr(sb);
		System.out.println("After    = " + sb);
	}
	private static void changeStr(StringBuffer sb) {
		sb.append("haha");
	}

结果:

Before   = test2
After    = test2haha

这里改变了值,已经引起不了大家的大惊小怪了。实质上跟上面的Person对象样例是类似的。

sb将引用副本传递给changeStr方法。再在changeStr方法中调用append方法。实质上是在改变两个引用共同指向的空间的值。不是引用传递也不是引用指向了别的空间。



最后吐槽一下,好热啊。

























以上是关于Java中的值传递与“引用传递”的主要内容,如果未能解决你的问题,请参考以下文章

关于java中的值传递与引用传递遇到的问题

第002弹:Java 中的值传递和引用传递

一道经典面试题:字符串在Java中如何通过“引用”传递

abap 值传递 引用传递

辨析Java方法参数中的值传递和引用传递

Java中的值传递和引用传递