1. String类为什么是final的?
答:
- 为了实现字符串常量池;
- 为了线程安全;
- 为了实现String可以创建HashCode不可变性。
分析:
首先,我们要知道关键字final的用途,它用于变量、方法或类时,含义各不相同。
- 变量:一旦初始化,变量值就不能修改。
- 方法:该方法不能被子类重写。
- 类:该类不能派生子类。
然后,我们再来看“String类为什么是final的?”这个问题。
查看JDK String类源码:
/**
* ...
* Strings are constant; their values cannot be changed after they
* are created. String buffers support mutable strings.
* ...
*/
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
final修饰的String,代表了String的不可继承性;final修饰的char[]代表了value不可变。但是,虽然final代表了不可变,但仅仅是引用地址不可变,并不代表了数组本身不可变。
编译器报错,不允许把value指向另一个地址。
对final修饰的value数组元素直接改变也是可以的。
private final char value[]这一句里,private的私有访问权限的作用都比final大。正是因为两者保证了String的不可变性。
只有String是不可变的,字符串常量池的实现,可以节省内存空间,提高效率(因为不同的字符串变量都指向池中的同一个字符串)。
只有String是不可变的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。
只有String是不可变的,在它创建的时候HashCode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。
https://blog.youkuaiyun.com/danceinkeyboard/article/details/72858374
https://blog.youkuaiyun.com/bn493235694/article/details/79599883
https://www.jianshu.com/p/9c7f5daac283