对String值不可变的理解以及String类型的引用传递问题
今天复习java时,突然注意到了一句以前没有注意过的一句话,String 是final修饰的,其值是不可变的。当时看的一脸懵逼,String str = "abc"; str = "abcde"这两行代码没有任何的错误的。上网百度了许久,还是整理下来防止以后忘记吧。
首先要理解的是,string说的不可变是其值不可变,比如String str = "abc",不可变值得是abc不可变,当我们str = “abcde”时,abc没有被销毁,仍然存放在常量池中,只不过是让str指向了“abcde”的内存地址。所以就算不停的赋值,改变的也只是str引用的地址问题,右边的值是不改变的。就举个String类型的引用传递来详细说明下吧
[java] view plain copy- public class Test {
- public static String appStr(String a){
- a += "bbb";
- return a;
- }
- public static StringBuilder appSb(StringBuilder sb){
- sb.append("bbb");
- return sb;
- }
- public static void main(String[] args) {
- String s = "aaa";
- String s2 = Test.appStr(s);
- //注意这边打印的是s,不是s2
- System.out.println(s);
- StringBuilder sb = new StringBuilder("aaa");
- StringBuilder sb2 = Test.appSb(sb);
- //注意这边打印的是sb,不是sb2
- System.out.println(sb.toString());
- }
- }
上输代码的输出结果是
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的不可变了。