对String值不可变的理解以及String类型的引用传递问题

来源:blog.csdn.net 更新时间:2023-05-25 21:55

今天复习java时,突然注意到了一句以前没有注意过的一句话,String 是final修饰的,其值是不可变的。当时看的一脸懵逼,String str = "abc"; str = "abcde"这两行代码没有任何的错误的。上网百度了许久,还是整理下来防止以后忘记吧。

首先要理解的是,string说的不可变是其值不可变,比如String str = "abc",不可变值得是abc不可变,当我们str = “abcde”时,abc没有被销毁,仍然存放在常量池中,只不过是让str指向了“abcde”的内存地址。所以就算不停的赋值,改变的也只是str引用的地址问题,右边的值是不改变的。就举个String类型的引用传递来详细说明下吧

[java] view plain copy
  1. public class Test {  
  2.       
  3.     public static String appStr(String a){  
  4.         a += "bbb";  
  5.         return a;  
  6.     }  
  7.       
  8.     public static StringBuilder appSb(StringBuilder sb){  
  9.         sb.append("bbb");  
  10.         return sb;  
  11.     }  
  12.       
  13.     public static void main(String[] args) {  
  14.         String s = "aaa";  
  15.         String s2 = Test.appStr(s);  
  16.         //注意这边打印的是s,不是s2  
  17.         System.out.println(s);  
  18.           
  19.         StringBuilder sb = new StringBuilder("aaa");  
  20.         StringBuilder sb2 = Test.appSb(sb);  
  21.         //注意这边打印的是sb,不是sb2  
  22.         System.out.println(sb.toString());  
  23.     }  
  24. }  

上输代码的输出结果是

aaa
aaabbb

 

下面来分析一下当运行到Test.appStr(s)时,将s(实参)的地址传递给a(形参),此时a="aaa",a+="bbb"之后,a="aaabbb",但是由于string是不可变的,所以在内存上就会重新分配一片内存空间给aaabbb,然后a指向该地址;而s的指向地址却没有发生改变,所以s的值打印出来仍然是aaa;

同理分析StringBuilder,也是引用类型,传递的是地址值,当形参sb传递给实参sb之后,方法对sb进行了修改,sb的值发生了改变(并不像string一样值不可变,重新分配空间),所以运行之后sb的指向值就发生了改变,随后打印的就是aaabbb了。

这样应该就可以理解String的不可变了。