2022-05-20String不可变

1.什么是不可变?

image.png

[图片上传中...(image.png-57137f-1653059235638-0)]

为什么String是不可变得呢?

public final class String implements java.io.Serializable, Comparable, CharSequence {
    /** String本质是个char数组. 而且用final关键字修饰.*/
    private final char value[];
    ...
    ...
}

String类final进行修饰,value数组final修饰,使得String无法继承,value是无法进行更改的,但是这里的更改指的是stack中的value的引用地址是不能发生改变的,但是Array数组是可变的,就是我们的堆之中的数据是可以改变的,这样当我们的数据进行改变之后,其实产生了一个新的对象、新的地址,但是原来的value的应用的对象个地址是没有发生改变的,我们可以用一个新的引用来获取到这个新的地址、新的对象
比如:

class Test{
    //不可变的String
    public static String appendStr(String s){
        s+="bbb";
        return s;
    }

    //可变的StringBuilder
    public static StringBuilder appendSb(StringBuilder sb){
        return sb.append("bbb");
    }

    public static void main(String[] args){
        //String做参数
        String s=new String("aaa");
        String ns=Test.appendStr(s);
        System.out.println("String aaa >>> "+s.toString());

        //StringBuilder做参数
        StringBuilder sb=new StringBuilder("aaa");
        StringBuilder nsb=Test.appendSb(sb);
        System.out.println("StringBuilder aaa >>> "+sb.toString());
    }
}
//Output: 
//String aaa >>> aaa
//StringBuilder aaa >>> aaabbb

其中我们发现s是不可变,ns就是我们的新的引用。

好处:安全

拿hashSet举例,我们知道HashSet其中的键值是存在唯一性的,当我们使用Stringbulider来进行存储,也就是字符串可变,那么当我们向HashSet中加入多个StringBuilder键值的时候,存在一个问题就是,后续若是我们将StringBuilder的值进行更改,若是使得其中的两个键值相等,这样就会破坏Hashset的唯一性,

常量池属性:

相同的String常量指向同一个内存地址


image.png

这样在大量使用字符串的情况下,可以节省内存空间,提高效率。但之所以能实现这个特性,String的不可变性是最基本的一个必要条件。要是内存里字符串内容能改来改去,这么做就完全没有意义了。

你可能感兴趣的:(2022-05-20String不可变)