String类的存储是通过final修饰的char[]数组来存放结果的。不可更改。所以每次当外部一个String类型的引用传递到方法内部时候,只是把外部String类型变量的引用传递给了方法参数变量。对的。外部String变量和方法参数变量都是实际char[]数组的引用而已。所以当我们在方法内部改变这个参数的引用时候,因为char[]数组不可改变,所以每次新建变量都是新建一个新的String实例。很显然外部String类型变量没有指向新的String实例。所以也就不会获取到新的更改。
下面程序例子假定tString指向A内存空间,A内存空间存放了”hello”这个字符串,然后调用modst函数将tString引用赋值给了text引用,注意是引用。确实是传址,我们知道String是不可变的,任何进行更改的操作都会产生新的String实例。所以在方法里面text指向了B空间,B空间存放了”sdf” 字符串,但是这个时候tString还是指向A空间,并没有指向B空间。
两次输出结果都是
hello
hello
Java字符串的参数传递为何没改变原本的值
例题
public class StringTest{
String str = new String("good");
char[] ch = {'t', 'e', 's', 't'};
public void change(String str, char ch[]){
str = "Hello";
ch[0] = 'b';
}
public static void main(String[] args){
StringTest s = new StringTest();
s.change(s.str, s.ch);
System.out.println(str);//输出good
System.out.println(ch);//输出best
}
}
解析
请牢记值传递机制,即:变量是什么就传什么值给形参。
本题change()中,传入了s的属性str的值(地址)给了形参str,然后再对形参str进行赋值。在这个过程中,没有通过属性str存储的地址对地址的数据进行任何修改(String类型也基本上是不能被修改的),而属性本身的地址值是不可能变的,所以方法执行后属性是不变的。
总结
值传递,所以只是将变量的值传递给了形参(数据或地址值)
想修改原来地址的数据只有通过传地址值的方式,并且通过这个地址值对数据进行修改
传参数之后,原来变量的存储的值是不会变的:地址值不可能变化,只是地址指向的内容可能改变了;基本数据类型变量的数据也不可能改变
字符串存储的内容(常量池中)无特殊情况是不能通过地址值改变的,只可能通过改变地址值来改变指向内容。所以字符串变量可以和基本数据类型基本等同看待,即传参调用后原本的值是不会改变的。