zoukankan      html  css  js  c++  java
  • String类为什么是不可变的

    String类为啥是final的?

    我们找到string的jdk源码

     1.看到String类被final修饰。这里你就要说出被final修饰的类不能被继承,方法不能被重写,变量不能被修改。

    2.看到final修饰的char[]代表了被存储的数据不可更改性。但是:虽然final代表了不可变,但仅仅是引用地址不可变,并不代表了数组本身不会变,请看下面图片

    上图说明:数组中的值发生了改变。

     

     上图说明:无论如何修改,数组的地址值不会改变。

    综上:所以在这里只有final修饰是不能确保string的不可变性。还需要privite修饰。才能确保不可变性。

    • 因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。
    •  因为字符串是不可变的,所以在它创建的时候HashCode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。

    除了 String 类,系统类库中还提供了一些其他的不可变类,基本类型的包装类、BigInteger、BigDecimal等等。这些不可变类比可变类更加易于设计、实现和使用,不容易出错且更加安全。另外,要记住并不仅仅是靠一个 final 关键字来实现不可变的,更多的是靠类内部的具体实现细节。


    String真的不可变吗?

     
    综上所述,String 的确是个不可变类,但是真的没有办法改变 String 对象的值吗?答案肯定是否定的,反射机制可以做到很多平常做不到的事情。
    String str = "123";
    System.out.println(str);
    Field field = String.class.getDeclaredField("value");
    field.setAccessible(true);
    char[] value = (char[]) field.get(str);
    value[1] = '3';


    执行结果:
    123
    133
    很显然,通过反射可以破坏 String 的不可变性。

    参考:https://blog.csdn.net/weixin_44946052/article/details/89409188

    https://www.jianshu.com/p/9c7f5daac283

    https://segmentfault.com/a/1190000009914328

    作者:MuRongKang
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    plsql查询中文乱码
    ORA-12514: TNS:listener does not currently know of service requested in connect
    linux 手动配置ip地址方法
    开机自起tomcat
    (静默安装)Cent OS 6_5(x86_64)下安装Oracle 11g
    Linux下启动Oracle服务和监听程序
    linux下强制安装rpm包
    谷歌浏览器如何将整个网页保存为图片
    C语言移位和位运算
    MySQL连接的使用
  • 原文地址:https://www.cnblogs.com/mukk/p/12263356.html
Copyright © 2011-2022 走看看