• Java String字符串的不可变


    Java 通过把String类设计为final使类不可继承,将变量value设置为private并且是final的,且value没有setter方法,不可修改。

    为什么这么设计:

    1.字符串常量池的需要.
    字符串常量池可以将一些字符常量放在常量池中重复使用,避免每次都重新创建相同的对象、节省存储空间。但如果字符串是可变的,此时相同内容的String还指向常量池的同一个内存空间,当某个变量改变了该内存的值时,其他遍历的值也会发生改变。所以不符合常量池设计的初衷。

    2. 线程安全考虑
    同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。

    3. 类加载器要用到字符串,不可变性提供了安全性,以便正确的类被加载。譬如你想加载java.sql.Connection类,而这个值被改成了myhacked.Connection,那么会对你的数据库造成不可知的破坏。

    4. 支持hash映射和缓存。
    因为字符串是不可变的,所以在它创建的时候hashcode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。

    • 安全

      • 引发安全问题,譬如,数据库的用户名、密码都是以字符串的形式传入来获得数据库的连接,或者在socket编程中,主机名和端口都是以字符串的形式传入。因为字符串是不可变的,所以它的值是不可改变的,否则黑客们可以钻到空子,改变字符串指向的对象的值,造成安全漏洞

      • 保证线程安全,在并发场景下,多个线程同时读写资源时,会引竞态条件,由于 String 是不可变的,不会引发线程的问题而保证了线程

      • HashCode,当 String 被创建出来的时候,hashcode也会随之被缓存,hashcode的计算与value有关,若 String 可变,那么 hashcode 也会随之变化,针对于 Map、Set 等容器,他们的键值需要保证唯一性和一致性,因此,String 的不可变性使其比其他对象更适合当容器的键值。

    • 性能

      • 当字符串是不可变时,字符串常量池才有意义。字符串常量池的出现,可以减少创建相同字面量的字符串,让不同的引用指向池中同一个字符串,为运行时节约很多的堆内存。若字符串可变,字符串常量池失去意义,基于常量池的String.intern()方法也失效,每次创建新的 String 将在堆内开辟出新的空间,占据更多的内存

    通过反射可以修改不可变对象,

    //创建字符串"Hello World", 并赋给引用s  
            String s = "Hello World";   
              
            System.out.println("s = " + s);    // Hello World  
              
            //获取String类中的value字段  
            Field valueFieldOfString = String.class.getDeclaredField("value");  
              
            //改变value属性的访问权限  
            valueFieldOfString.setAccessible(true);  
              
            //获取s对象上的value属性的值  
            char[] value = (char[]) valueFieldOfString.get(s);  
              
            //改变value所引用的数组中的第5个字符  
            value[5] = '_';  
              
            System.out.println("s = " + s);    //Hello_World 
  • 相关阅读:
    前端常用模板引擎- artTemplate
    Vue-多级组件嵌套传值
    echarts图表常用到的设置
    react-基础入门分享
    vue中 export const 和 export default的区别
    vue安装依赖报错
    nvm-node版本控制工具
    gulp-入门
    vue 中使用 iconfont
    c3中基本动画
  • 原文地址:https://www.cnblogs.com/huangyin/p/8545556.html
Copyright © 2020-2023  润新知