从一道面试题开始:
1 public class test1{ 2 String str=new String("good"); 3 char[] ch={'a','b','c'}; 4 public static void main(String[] args){ 5 test1 ex=new test1(); 6 ex.change(ex.str,ex.ch); 7 System.out.println(ex.str+"and"); 8 System.out.println(ex.ch); 9 } 10 public void change(String str,char ch[]){ 11 str="test ok"; 12 ch[0]='g'; 13 } 14 }
运行的结果是
goodand
gbc
这道题很简单,主要考察的是值传递与引用传递,我想大家都很清楚。
由这道题出发,我主要想讨论一下的是string和char[]传递的区别。虽然string不属于基本数据类型,理应是引用传递,但为什么会出现上面的结果。
为此,我们再看一段代码 :
1 class test1{ 2 public static void main(String[] args){ 3 String s="aa"; 4 int i=System.identityHashCode(s); 5 System.out.println(i); 6 System.out.println("-----------------"); 7 test(s); 8 } 9 public static void test(String s){ 10 int i=System.identityHashCode(s); 11 System.out.println(i); 12 System.out.println("-----------------"); 13 s="dd"; 14 int j=System.identityHashCode(s); 15 System.out.println(j); 16 } 17 }
运行结果为
366712642 ----------------- 366712642 ----------------- 1829164700
从上面4、5和10、11可以看出,当初始传过去的时候,main中的s和test中的s指向同一个地址,当我们给s赋值后,s指向了另一区间。为了说明问题,我们再看看char[]传递:
1 class test1{ 2 public static void main(String[] args){ 3 char[] a={'1'}; 4 int i=System.identityHashCode(a); 5 System.out.println(i); 6 System.out.println("-----------------"); 7 test(a); 8 } 9 public static void test(char[] s){ 10 int i=System.identityHashCode(s); 11 System.out.println(i); 12 System.out.println("-----------------"); 13 s[0]='d'; 14 int j=System.identityHashCode(s); 15 System.out.println(j); 16 } 17 }
结果为
366712642 ----------------- 366712642 ----------------- 366712642
char[]传递的三个结果是一样的,为此我们可以明白了最初的面试题的结果。
总结:string传递过去后和原变量指向同一地址,但当给string赋值后string指向了不同的地址,这正是string的不变性,对这一点可以做如下解释,
当给string赋值时会先去常量池里去找有没有这一变量,如果有,就让string指向这一地址,如果没有则新开辟一个。如下代码:
class test1{ public static void main(String[] args){ String s="1"; int i=System.identityHashCode(s); System.out.println(i); System.out.println("-----------"); String s1="1"; int i1=System.identityHashCode(s1); System.out.println(i1); } } 结果 366712642 ----------- 366712642