开发者社区> 问答> 正文

为什么String在Java中是不可变的?

为什么String在Java中是不可变的?

展开
收起
珍宝珠 2020-02-07 16:36:16 1176 0
2 条回答
写回答
取消 提交回答
  • Java中String被设计成不可变主要是考虑到效率与安全方面。

    2020-03-29 13:16:40
    赞同 展开评论 打赏
  • 字符串在Java中是不可变的,因为String对象缓存在String池中。由于缓存的字符串在多个客户之间共享,因此始终存在风险,其中一个客户的操作会影响所有其他客户。例如,如果一段代码将String“Test”的值更改为“TEST”,则所有其他客户也将看到该值。由于String对象的缓存性能是很重要的一方面,因此通过使String类不可变来避免这种风险。

    同时,String是final的,因此没有人可以通过扩展和覆盖行为来破坏String类的不变性、缓存、散列值的计算等。String类不可变的另一个原因可能是由于HashMap。

    由于把字符串作为HashMap键很受欢迎。对于键值来说,重要的是它们是不可变的,以便用它们检索存储在HashMap中的值对象。由于HashMap的工作原理是散列,因此需要具有相同的值才能正常运行。如果在插入后修改了String的内容,可变的String将在插入和检索时生成两个不同的哈希码,可能会丢失Map中的值对象。

    如果你是印度板球迷,你可能能够与我的下一句话联系起来。字符串是Java的VVSLaxman,即非常特殊的类。我还没有看到一个没有使用String编写的Java程序。这就是为什么对String的充分理解对于Java开发人员来说非常重要。

    String作为数据类型,传输对象和中间人角色的重要性和流行性也使这个问题在Java面试中很常见。

    为什么String在Java中是不可变的是Java中最常被问到的字符串访问问题之一,它首先讨论了什么是String,Java中的String如何与C和C++中的String不同,然后转向在Java中什么是不可变对象,不可变对象有什么好处,为什么要使用它们以及应该使用哪些场景。这个问题有时也会问:“为什么String在Java中是final的”。在类似的说明中,如果你正在准备Java面试,我建议你看看Java编程面试公开书,这是高级和中级Java程序员的优秀资源。它包含来自所有重要Java主题的问题,包括多线程,集合,GC,JVM内部以及Spring和Hibernate框架等。

    正如我所说,这个问题可能有很多可能的答案,而String类的唯一设计者可以放心地回答它。我在JoshuaBloch的EffectiveJava书中期待一些线索,但他也没有提到它。我认为以下几点解释了为什么String类在Java中是不可变的或final的:

    1)想象字符串池没有使字符串不可变,它根本不可能,因为在字符串池的情况下,一个字符串对象/文字,例如“Test”已被许多参考变量引用,因此如果其中任何一个更改了值,其他参数将自动受到影响,即假设

    image.png

    现在字符串B调用"Test".toUpperCase(),将同一个对象改为“TEST”,所以A也是“TEST”,这不是期望的结果。

    下图显示了如何在堆内存和字符串池中创建字符串。

    image.png

    2)字符串已被广泛用作许多Java类的参数,例如,为了打开网络连接,你可以将主机名和端口号作为字符串传递,你可以将数据库URL作为字符串传递,以打开数据库连接,你可以通过将文件名作为参数传递给FileI/O类来打开Java中的任何文件。如果String不是不可变的,这将导致严重的安全威胁,我的意思是有人可以访问他有权授权的任何文件,然后可以故意或意外地更改文件名并获得对该文件的访问权限。由于不变性,你无需担心这种威胁。这个原因也说明了,为什么String在Java中是最终的,通过使java.lang.Stringfinal,Java设计者确保没有人覆盖String类的任何行为。

    3)由于String是不可变的,它可以安全地共享许多线程,这对于多线程编程非常重要.并且避免了Java中的同步问题,不变性也使得String实例在Java中是线程安全的,这意味着你不需要从外部同步String操作。关于String的另一个要点是由截取字符串SubString引起的内存泄漏,这不是与线程相关的问题,但也是需要注意的。

    4)为什么String在Java中是不可变的另一个原因是允许String缓存其哈希码,Java中的不可变String缓存其哈希码,并且不会在每次调用String的hashcode方法时重新计算,这使得它在Java中的HashMap中使用的HashMap键非常快。简而言之,因为String是不可变的,所以没有人可以在创建后更改其内容,这保证了String的hashCode在多次调用时是相同的。

    5)String不可变的绝对最重要的原因是它被类加载机制使用,因此具有深刻和基本的安全考虑。如果String是可变的,加载“java.io.Writer”的请求可能已被更改为加载“mil.vogoon.DiskErasingWriter”.安全性和字符串池是使字符串不可变的主要原因。顺便说一句,上面的理由很好回答另一个Java面试问题:“为什么String在Java中是最终的”。要想是不可变的,你必须是最终的,这样你的子类不会破坏不变性。你怎么看?

    2020-02-07 16:52:57
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载