美文网首页
关于 String

关于 String

作者: Rayeston | 来源:发表于2018-01-22 09:26 被阅读0次

1. String 不可变

  • 不可变对象

    对象在创建完成之后,其状态不能再被改变,则该对象即为不可变对象
  • 对象不可变具体内容

    不能改变对象内的成员变量
    基本数据类型的值不能改变
    引用类型的变量不能指向其他对象
    引用类型所指向的对象状态也不能改变
  • 例如

    String s = "ABC"; 
    System.out.print(s);  // ABC
    s = "123";  
    System.out.print(s);  // 123
    
  • 执行结果

    "ABC"
    "123"
    
  • 释义

对象:在内存中是一块内存区,成员变量越多,这块内存区占的空间越大。
引用:只是一个4字节的数据,里面存放了它所指向的对象的地址,通过这个地址可以访问对象。

  • s只是一个引用,它指向了一个具体的对象,当s=“123”; 这句代码执行过之后,又创建了一个新的对象“123”, 而引用s重新指向了这个新的对象,原来的对象“ABC”还在内存中存在,并没有改变。
  • 不能直接操作对象本身,所有的对象都由一个引用指向,必须通过这个引用才能访问对象本身,包括获取成员变量的值,改变对象的成员变量,调用对象的方法等
  • 效率和安全
Java 将 String 设成不可变最大的原因是效率和安全
  • 提高字符串常量池的效率和安全性
  • 如果一个对象是不可变的 ,需要拷贝的对象的内容时就不用复制它本身,而只是复制它的地址,复制地址(通常一个指针的大小)需要很小的内存,效率也很好
  • 对于引用同一个对象的其他变量也不会造成影响
  • 对于多线程是安全的。多线程同时进行时,一个可变对象的值很可能被其他线程改变

2. String 源码

  • JDK1.7以后,String 类的成员变量只剩下两个:


    String 类成员变量.png
  • 释义
    • String 类实际上是对字符数组的封装。
    • 成员变量 hash,是该 String 对象的哈希值的缓存。
    • 在 Java 中,数组也是对象,所以 value 也只是一个引用,它指向一个真正的数组对象。在执行第一句代码时,真正的内存排布如下图: String 内存数据.png
  • String 对象不可变
    • String 内部成员变量 value 和 hash 并未对外提供 setter 方法,且变量 value 是 final 的。这些都说明一旦 String 内部的 value 被初始化后,便不会再改变,故而 String 对象不会改变。
  • 至于 String 内部其他方法:如 replace() 在执行后,结果发生的变化,也是同理。即:这些方法执行过程中,会生成新的 String 对象,该对象将会被赋值给引用,而原来的对象并未改变。如: String 新对象.png
  • 值得注意的是,通过反射可以修改对象的值。如:

     public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    
          String s = "Hello World";
          System.out.println("s: " + s);
          // 获取String类中的value字段
          Field valueFieldOfString= String.class.getDeclaredField("value");
          // 设置访问权限
          valueFieldOfString.setAccessible(true);
          // 获取 s 对象上的value属性的值
          char[] value = (char[]) valueFieldOfString.get(s);
          // 改变value所引用的数组中的第 5 个字符
          value[5] = '_';
          System.out.println("s: " + s); // Hello_World
    }

相关文章

网友评论

      本文标题:关于 String

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