面试-java基础-为什么String定义为final?

“ 为什么 String 定义为 final ” 的其它问法:why String is immutable in Java ?why String is final in Java ?

虽然问题是短短的一句话:“为什么 String 定义为 final ?”。但问题表面下知识点可不止一点两点,为了更好的理解并回答这个问题。

一、 Stringfinal 在什么地方?
...
 * Strings are constant; their values cannot be changed after they
 * are created. String buffers support mutable strings.
 * Because String objects are immutable they can be shared.
...
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
	private final char value[];
	...
}

String 类中的注释有这样一句话 Strings are constant;their values cannot be changed after they are created. ... Because String objects are immutable they can be shared.

String 类被 final 修饰,说明 String 类不能被继承,即没有人可以通过拓展(extending)或重写(overriding)来破坏 String 的不可变性(immutability)、缓存(cache)和哈希值(hashCode calculation)。

二、回答这个问题的角度
  • 内存(memory)
  • 同步(synchronization)
  • 数据结构(data structure)
1、字符串常量池(String pool)

字符串常量池是方法区中一个特殊的内存区域。在创建字符串时,如果该字符串已经存在于常量池,则返回现有字符串的引用,而不是创建一个新的对象。
例如,如下例子只会创建一个字符串,而不是两个。

String s1 = "abc";
String s2 = "abc";

JVM的行为图如下
在这里插入图片描述
如果字符串是可变的,修改一个一个引用的字符串值将会导致另一个引用值也发生变化,这明显是不可以的。

2、哈希值(caching hashcode)

字符串的hashCode被频繁的用在hashMaphashSet中。不可变性保证了hashCode字符串一旦创建,hashCode就不会再发生变化,不用每次都需要重新计算hashCode(实际上,对象的hashCode会延后到真正调用Object::hashCode()方法时才计算),这使得进行与hashCode有关的操作时更加有效率。

3、便于其他对象的使用
HashSet<String> set = new HashSet<String>();
set.add(new String("a"));
set.add(new String("b"));
set.add(new String("c"));
 
for(String a: set)
	a.value = "a";

如果String是可变的,修改value值将会导致set集合中存在重复的元素,这会违反set集合中不包含重复值的设计。

4、安全

String被广泛用作许多java类的参数,例如网络连接、打开文件等。如果字符串不是不可变的,连接或文件将被更改,这将导致严重的安全威胁。该方法认为它连接到一台机器上,但不是。可变字符串也可能在反射中导致安全问题,因为参数是字符串。

字符串是不可变的最重要的原因是类加载机制使用了它,因此具有深刻和基本的安全性。如果字符串是可变的,一个请求加载java.ioWriter可能会被改成mil.vogo.diskerasingwriter

5、不可变的对象天生就是线程安全的

因为不可变对象不能被更改,所以它们可以在多个线程之间自由地共享。这就消除了同步的需求。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值