请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

为什么 String 是不可变的?

[复制链接]
查看: 14|回复: 0

2万

主题

2万

帖子

7万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
76556
发表于 2020-9-16 00:49 | 显示全部楼层 |阅读模式
作者:Yujiaao
https://segmentfault.com/a/1190000019962661
我最喜欢的 Java 面试问题,不好回答,但同时也非常有用。一些面试者也常问这个问题,为什么 String 在 Java 中是final的。
字符串在 Java 中是不可变的,因为 String 对象缓存在 String 池中。由于缓存的字符串在多个客户之间共享,因此始终存在风险,其中一个客户的操作会影响所有其他客户。
例如,如果一段代码将 String “Test” 的值更改为 “TEST”,则所有其他客户也将看到该值。由于 String 对象的缓存是性能的重要保证,因此通过使 String 类不可变来避免这种风险。
同时,String 是 final 的,因此没有人可以通过扩展和覆盖行为来破坏 String 类的不变性、缓存、散列值的计算等。String 类不可变的另一个原因可能是由于HashMap
由于把字符串作为 HashMap 键很受欢迎。对于键值来说,不可变性是非常的重要,以便用它们检索存储在 HashMap 中的值对象。由于 HashMap 的工作原理是散列,因此需要具有相同的值才能正常运行。如果在插入后修改了 String 的内容,可变的 String 将在插入和检索时生成两个不同的哈希码,可能会丢失 Map 中的值对象。
字符串是Java 非常特殊的类。我还没有看到一个没有使用 String 编写的 Java 程序。这就是为什么对 String 的充分理解对于 Java 开发人员来说非常重要。关注微信公众号:Java技术栈,在后台回复:Java,可以获取我整理的 N 篇 Java 教程,都是干货。
String 是数据类型,也传输对象和中间人。这种多重角色的重要性和流行性, 也使这个问题在 Java 面试中很常见。
为什么 String 在 Java 中是不可变的是 Java 中最常被问到的字符串访问问题之一,它首先讨论了什么是 String,Java 中的 String 如何与 C 和 C++ 中的 String 不同,然后转向在Java中什么是不可变对象,不可变对象有什么好处,为什么要使用它们以及应该使用哪些场景。
这个问题有时也会问:“为什么 String 在 Java 中是 final 的”。钻个牛角尖,你确定是不变的吗,看这篇:Java中的String真的是不可变的吗?在类似的说明中,如果你正在准备Java 面试,我建议你看看Java编程面试公开书,这是高级和中级Java程序员的优秀资源。它包含来自所有重要 Java 主题的问题,包括多线程,集合,GCJVM内部以及Spring和 Hibernate 框架等。
正如我所说,这个问题可能有很多可能的答案,而 String 类的唯一设计者可以放心地回答它。我在 Joshua Bloch 的 Effective Java 书中期待一些线索,但他也没有提到它。我认为以下几点解释了为什么 String 类在 Java 中是不可变的或 final 的:

  • 想象字符串池没有使字符串不可变,它根本不可能,因为在字符串池的情况下,一个字符串对象/文字,例如 “Test” 已被许多参考变量引用,因此如果其中任何一个更改了值,其他参数将自动受到影响,即假设
  1. StringA="Test";StringB="Test";
复制代码
现在字符串 B 调用"Test".toUpperCase(), 将同一个对象改为“TEST”,所以 A 也是 “TEST”,这不是期望的结果。
下图显示了如何在堆内存和字符串池中创建字符串。
我的关键词 为什么 String 是不可变的?  新闻咨询 1218593-20200421135535748-722526756


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

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

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

  • String 不可变的绝对最重要的原因是它被类加载机制使用,因此具有深刻和基本的安全考虑。如果 String 是可变的,加载“java.io.Writer” 的请求可能已被更改为加载 “mil.vogoon.DiskErasingWriter”. 安全性和字符串池是使字符串不可变的主要原因。
顺便说一句,上面的理由很好回答另一个Java面试问题: “为什么String在Java中是最终的”。要想是不可变的,你必须是最终的,这样你的子类不会破坏不变性。你怎么看?
推荐去我的博客阅读更多:
1.Java JVM、集合、多线程、新特性系列教程
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
4.Java、后端、架构、阿里巴巴等大厂最新面试题
觉得不错,别忘了点赞+转发哦!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表