zoukankan      html  css  js  c++  java
  • 有没有想过String为什么设计为不可变对象

    1.声明为final类的目的:

    主要目的就是保证String是不可变(immutable)。不可变就是第二次给一个String 变量赋值的时候,不是在原内存地址上修改数据,而是重新指向一个新对象,新地址。下面看String类源码如何保证是不可变的:

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence
    {
        /** The value is used for character storage. */
        private final char value[];

    String类的主力成员字段value是个char[ ]数组,而且是用final修饰的。编译器不允许把value指向另一个地址。但可以直接对数组元素修改。为了保证这个数组元素不能修改,做了如下措施:
    (1)所有String的方法里很小心的没有去动数组里的元素,没有暴露内部成员字段。
    (2)避免被其他人继承后破坏,整个String设成final禁止继承。如果有一个String的引用,它引用的一定是一个String对象,而不可能是其他类的对象。

    2.为什么要把String设计为不可变

    • 从内存角度分析:

       字符串常量池的要求:创建字符串时,如果该字符串已经存在于池中,则将返回现有字符串的引用,而不是创建新对象。多个String变量引用指向同一个内地地址。如果字符串是可变的,用一个引用更改字符串将导致其他引用的值错误。这是很危险的。

    • 缓存Hashcode:

       字符串的Hashcode在java中经常配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。不可变的特性保证了hashcode永远是相同的。不用每次使用hashcode就需要计算hashcode。这样更有效率。因为当向集合中插入对象时,是通过hashcode判别在集合中是否已经存在该对象了(不是通过equals方法逐个比较,效率低)。

    • 方便其它类使用:

       其他类的设计基于string不可变,如set存储string,改变该string后set包含了重复值。

    • 安全性:

       String被广泛用作许多java类的参数,例如网络连接、打开文件等。如果对string的某一处改变一不小心就影响了该变量所有引用的表现,则连接或文件将被更改,这可能导致严重的安全威胁。
    不可变对象不能被写,所以不可变对象自然是线程安全的,因为不可变对象不能更改,它们可以在多个线程之间自由共享。

    总结 :由于效率和安全性的原因,字符串被设计为不可变!

  • 相关阅读:
    http 400 错误的请求怎么解决
    HTTP 404
    怎样在WIN7系统下安装IIS
    未能找到类型或命名空间名称“XXXX”(是否缺少 using 指令或程序集引用?) 转
    错误 1 未能找到元数据文件“C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/Temporary ASP.NET Files/wwwroot/7cb4fcd
    mklink命令转移win7系统盘文件夹users和programdata(附xp的方法)
    前端进阶之路:初涉Less
    原生js实现tooltip提示框的效果
    jquery+css实现邮箱自动补全
    前端面试中常见的算法问题读后整理
  • 原文地址:https://www.cnblogs.com/luckyjcx/p/12988930.html
Copyright © 2011-2022 走看看