String是值传递还是引用传递

        Java参数传递分为值传递和引用传递,基本类型是值传递,封装的对象时引用传递。

        先看一下值传递,引用传递和String参数传递的Demo:

值传递:

/**
 * 值传递
 * @author Administrator
 *
 */
public class Demo29 {
	public static void main(String[] args) {
		boolean flag = false;
		test29(flag);
		System.out.println(flag);
	}
	
	public static void test29(boolean flag) {
		flag = true;
	}
}

值传递的结果是:

false

分析:

flag传入test29()方法时,jvm实际上是复制了一份参数传入方法中。

可以理解成传入方法的参数是temp,值是false。

方法里的flag = true;可以理解成给temp赋值true。

System.out输出的参数实际上是main方法中定义的flag,跟test29()方法里的temp参数没有半毛钱关系。

从内存分配的角度来看,栈中是有两个变量的。一个是main方法中定义的flag,另外一个是在传参时jvm复制的一份flag,我们就叫它temp。不论temp值怎么改变,flag是不会变的。

 

引用传递:

/**
 * 引用传递
 * @author Administrator
 *
 */
public class Demo30 {
	public static void main(String[] args) {
		Person person = new Person();
		person.setA(12);
		change(person);
		System.out.println(person.getA());
	}
	
	public static void change(Person person) {
		person.setA(15);
	}
}

class Person{
	private int a;

	public int getA() {
		return a;
	}

	public void setA(int a) {
		this.a = a;
	}
	
}

引用传递结果:

15

分析:

main方法new Person时,jvm在堆中分配了一块内存用于存放Person对象。并且在栈中存放一个person对象,值是指向堆中Person对象的地址。

把person变量传入change()方法时,jvm复制了一份person变量。为了便于理解我们叫它temp,temp的值和person是一样的,都是指向堆中Person对象的地址。

Person对象的属性的值改变时,person变量指向的是Person,所以输出person指向的对象的属性的值,就是改变过后的值。

 

String参数传递: 

/**
 * String
 * @author Administrator
 *
 */
public class Demo31 {
	public static void main(String[] args) {
		String str = "abc";
		change(str);
		System.out.println(str);
	}
	
	public static void change(String str) {
		str = "bcd";
	}
}

String参数传递结果:

abc

分析:

jvm在实例化字符串时会使用字符串常量池,把str作为参数传入change()方法。jvm复制了一份str变量,为了便于理解我们叫它temp。这个时候str和temp都指向字符串常量池中的“abc”。

当我们给temp变量赋值“bcd”时,jvm会实例化“bcd”并将它放进常量池中。这个过程可以看成是:

temp = new String("bcd");

这个时候temp指向的是常量池中的“bcd”。

那么当我们输出str时,str指向的仍然是“abc”。

 

 

如果看完这篇仍然觉得不清楚,请移步下面两篇文章:

本文参考文章:

1.深入理解Java中的String:https://www.cnblogs.com/xiaoxi/p/6036701.html

2.String是值传递还是引用传递:https://www.cnblogs.com/boboooo/p/9066831.html

 

你可能感兴趣的:(API)