public class StringTest{
public static void main(String args[])
{
String str=new String("World");
char ch[]={'H','e','l','l','o'};
change(str,ch); System.out.print(str + " and ");
System.out.println(ch);
}
public static void change(String str, char ch[])
{
str="Changed"; ch[0]='C';
}
}
最后的结果是:
World and Cello
public static void main(String args[])
{
String str=new String("World");
char ch[]={'H','e','l','l','o'};
change(str,ch); System.out.print(str + " and ");
System.out.println(ch);
}
public static void change(String str, char ch[])
{
str="Changed"; ch[0]='C';
}
}
最后的结果是:
World and Cello
ch[0]='C';//这是与外部引用共同引用的数组对象的第一个元素被改变
这句话来自JDK的文档:字符串是常量;它们的值在创建之后不能改变。
之后在函数内部:形参str试图改变其指向的"World"->"Changed"
但不幸的是:由于String是常量不可以改变,所以就在内存中new 了一个“Changed"并把形参str指向了他
可惜此时实参并没有变
丢弃了,等着GC过来回收的
World and Cello
所以为什么我们经常要this.XXX=XXX,就是为了让我们方法里传进来的参数和真正我们要改变的变量关联起来
java也只对string有这样的处理。所以不要把string当一般对象看。
所以change函数的两个参数str 和 ch (形参)是和定义的变量(实参)的内存地址是一样的,或许你会认为在change函数里面改变str 和 ch后,原来的变量也会改变,所以你期望的结果是:Changed and Cello。 但是事实确实这样的:String对象没有被改变,ch[0]却被改变了,输出结果是:World and Cello。这个你应该会很快想到两种参数是否有差别? 原因就在于String类型是final的,一旦声明就无法被改变,所以当函数想改变形参str的时候,就为形参str用new重新分配了一个内存空间,此时形参str和实参str指向不同的内存空间,形参str改变了,但是实参依旧原地不动。ch[0]为什么不改变?原因就在于它是允许改变的,实参和形参依旧指向同一块内存。 所以根本原因就在于String是final的,一旦声明就不允许改变,而所谓的改变,其实是新new了一个String了的。 你也可以自己试试,用StringBuffer来替代String试试,结果应该是 Changed and Cello,StringBuffer和String的区别你应该会明白的