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

Posted toseemydream

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对String值不可变的理解以及String类型的引用传递问题相关的知识,希望对你有一定的参考价值。

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

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

  

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的不可变了。

对象一直存在且没有变化,只是指向发生了变换


以上是关于对String值不可变的理解以及String类型的引用传递问题的主要内容,如果未能解决你的问题,请参考以下文章

StringStringBuffer以及StringBuilder区别

1.字符型值不可变

String Stringbuilder Stringbuffer的区别

String类的深入理解(未完待续)

String in Java

Java String的理解