从一道面试题开始:
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 }
运行的结果是
goodandgbc
这道题很简单,主要考察的是值传递与引用传递,我想大家都很清楚。
由这道题出发,我主要想讨论一下的是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