查看原文
其他

为什么 String 要设计成 Final 类?

面试鸭 面试鸭 2024-03-29

题目

为什么 String 要设计成 Final 类?

推荐解析

1)只有当字符串是不可变的,字符串池才有可能实现

字符串池的实现可以在运行时节约很多 heap 空间,因为不同的字符串变量都指向池中的同一个字符串。但如果字符串是可变的,那么 String interning 将不能实现(注:String interning 是指对不同的字符串仅仅只保存一个,即不会保存多个相同的字符串),因为这样的话,如果变量改变了它的值,那么其它指向这个值的变量的值也会一起改变。

String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2); // 输出 true,因为字符串池中已经存在了 "Hello"

2)如果字符串是可变的,那么会引起很严重的安全问题

譬如,数据库的用户名、密码都是以字符串的形式传入来获得数据库的连接。因为字符串是不可变的,所以它的值是不可改变的,否则黑客们可以钻到空子,改变字符串指向的对象的值,造成安全漏洞。

3)因为字符串是不可变的,所以是多线程安全的

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

String str = "Hello";
new Thread(() -> System.out.println(str)).start();
new Thread(() -> System.out.println(str)).start();

4)类加载器要用到字符串,不可变性提供了安全性,以便正确的类被加载

譬如你想加载 Java.util.Long 类,而这个值被改成了 haha.Long,那么会对你的数据库造成不可知的破坏。

Class<?> clazz = Class.forName("java.lang.String");

5)作为 Map 的 key,提高了访问效率

在 Java 中,字符串是不可变的,所以它们的 hashcode 在创建时就被缓存了,不需要重新计算。这就使得字符串很适合作为 Map 中的键。

其他补充

鱼聪明 AI 的回答:

鱼聪明 AI 地址:

https://www.yucongming.com/

在 Java 中,String类被设计为final类,主要有以下几个原因:

  1. 安全性String类是不可变的,这意味着一旦创建,其值就不能被改变。这对于安全性来说是非常重要的,因为你可以安全地将敏感信息的一部分作为String对象的一部分,而不必担心它们会被修改。如果String类不是final的,那么你可能会创建一个子类,这个子类可能会修改String对象的值,这将破坏String类的不变性。

  2. 性能String类是不可变的,这意味着它的实例可以被多个线程安全地共享,而不需要使用额外的同步机制。这对于性能来说是非常重要的,因为在多线程环境中,频繁的同步操作可能会导致性能下降。

  3. 避免混淆:如果String类不是final的,那么你可能会创建一个子类,这个子类可能会改变String对象的行为。这将导致混淆,因为你可能不确定一个String对象的行为是由String类本身定义的,还是由它的子类定义的。通过将String类设计为final,你可以避免这种混淆。

  4. 避免继承导致的问题:如果String类不是final的,那么你可能会创建一个子类,这个子类可能会改变String对象的行为。这将导致一些问题,例如,如果你创建了一个子类,并将它与String对象进行比较,那么你可能会得到一个意外的结果。通过将String类设计为final,你可以避免这些问题。

总的来说,String类被设计为final类,是为了保证它的安全性、性能和行为的一致性。

CSDN 某同学的回答:

一旦 string 类可改变了。将违背 java 设计规则,即 hashcode 不同,equals 一定也不同。hashcode 相同,equals 可能相同。违背设计规则后,很多类的特性将失效。比如 set 集合,是不允许出现重复数据的。而强行改变 s 的值后,set 不许出现重复数据的特性将失效。

推荐文章

String 类为什么要被设计成 final 的:https://blog.csdn.net/efggfxfvhh/article/details/126520262

欢迎交流

通过阅读本文,你应该知道了为什么 String 要设计成 final 类,面试中你可能会回答为什么 String 不能被重写,String 底层原理是什么?但是关于为什么会被设计成 final 类可能会缺少了解,本文将会对你有所帮助。我在下面抛出以下几个问题,欢迎大家在评论区进行留言!

1.除了 String 类,Java 中还有哪些类被设计为 final 类?

2.在多线程环境中,如果 String 类不是 final,那么它的实例是否可以被多个线程安全共享?

3.如果 String 类不是 final 的,那么它的子类是否可以被用于替代 String 类?

往期推荐

沉淀 700 天,编程学习指南 2.0 发布啦!

对于 Java 中多态的理解是什么?

Java 什么时候类会被加载?

一键生成完美简历!刷完题记得改简历鸭~

什么是 Git 的 cherry-pick?

常见的垃圾回收算法有几种类型?

继续滑动看下一个
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存