美文网首页
关于String的问题解析

关于String的问题解析

作者: imu_studio | 来源:发表于2019-11-30 12:05 被阅读0次

    为什么String设计成不可变的

    1.字符串常量池的需要,提升效率和减少内存分配
    2.安全性考虑,防止被意外修改(HashSet中存的值如果是可变的String,则破坏了唯一性;不可被写所以线程安全;)
    3.作为HashMap、HashTable等hash型数据key的必要。因为不可变的设计,jvm底层很容易在缓存String对象的时候缓存其hashcode,这样在执行效率上会大大提升。

    为什么String对象是不可变的?

    看以下代码:

    String s  = "abcdef";
    s="123456"
    System.out.print(s);
    

    此时输出s:s="123456" 从打印结果可以看出,s的值确实改变了。大家可能以为那怎么还说String对象是不可变的呢? 其实这里存在一个误区: s只是一个String对象的引用,并不是对象本身。s这个引用从"abcdef",指向了"123456",对象本身一直是存在的。
    首先来看String类中的成员变量

      public final class String implements java.io.Serializable, Comparable<string>,       CharSequence {
         /** The value is used for character storage. */
        private final char value[];
        /** Cache the hash code for the string */
        private int hash; // Default to 0</string>
    

    以上代码可以看出来String类就是对字符数组的封装,hash成员变量是该String对象的哈希值的缓存。
    在Java中,数组也是对象,所以value成员变量也是一个引用,它指向一个真正的数组对象。
    由上面代码看出,value[]这个成员变量是final修饰的,也就是说在String类内部这个值初始化后就不能被修改,String对象就是不可变的。
    String中在存在一些其他方法,截取,替换等,都是创建新的对象。


    以下是关于字符串比较的解析

         String s1 = "abc";
         String s2 = "a"+"b"+"c";
         System.out.print(s1==s2);//true
         String s3 = new String("abc");//只要有关键字new,一定是开辟了新的空间
         String s4 = "a"+"bc";
         System.out.print(s4==s2);//true 常量+常量 javac会进行优化,会自动编译变成abc
         String s5="bc";
         String s6="a"+s5
         System.out.print(s6==s4); // false  常量与变量的运算,javac不进行任何优化,再执行得时候使用关键字new创建一个新的对象
    

    注意:String s3 = new String("abc");这句代码分两种情况:如果常量池种没有,回先在常量池中放一份,再往堆中存放一份,创建2次对象;如果常量池中有,就直接创建一次对象;

    相关文章

      网友评论

          本文标题:关于String的问题解析

          本文链接:https://www.haomeiwen.com/subject/yvgvwctx.html