可能是重复问题:
为什么Java中的String是final的?
在我的编程生涯中,有很多时候我希望String类不是final/sealed/NotInheritable的。
编程语言的设计者试图防止我做什么会使程序出现问题呢?
相反地,限制我扩展String类的目的是为了防止语言设计者所希望避免的错误。
您能列出可扩展字符串类的优缺点吗?
可能是重复问题:
为什么Java中的String是final的?
在我的编程生涯中,有很多时候我希望String类不是final/sealed/NotInheritable的。
编程语言的设计者试图防止我做什么会使程序出现问题呢?
相反地,限制我扩展String类的目的是为了防止语言设计者所希望避免的错误。
您能列出可扩展字符串类的优缺点吗?
String是一个不可变类,这意味着你在创建后无法修改它的状态。如果在将字符串传递到其他库或Map等地方后对其进行修改,结果将是不可预测的。
Java API的一个错误是BigInteger
和BigDecimal
不是final,这意味着当从不受信任的代码接收它们时需要执行防御性复制。相反,您始终可以相信一个String
将保持一致。
不受信任的BigInteger:
public class DestructiveBigInteger extends BigInteger {
public DestructiveBigInteger(String value) {
super(value);
}
public BigInteger add(BigInteger val) {
return BigInteger.ONE; // add() method does not behave correctly
}
public BigInteger subtract(BigInteger val) {
throw new UnsupportedOperationException("subtract is broken");
}
}
对于String
类型的对象,不可能实现同样的操作。如Effective Java中所述,您需要制作这些类型对象的防御性副本:
public void setValue(BigInteger value) {
this.value = new BigInteger(value.toByteArray());
}
字符串是不可变数据类型,因此它是final的。如果盲目扩展String,将会导致很多库依赖于String对象的不可变性而出现严重问题。
将String扩展为可变类型对于String经过的任何代码都是不可见的,但会产生非常令人惊讶和恶劣的副作用,例如突然无法从HashMap中加载值,即使你已经有了键的String,因为hashCode已经被劫持了。