问题描述
它在这篇文章中说:>
将一个类设为 final 是因为它是不可变的,这是这样做的一个很好的理由.
我对此有点困惑...我知道从线程安全性和简单性的 POV 来看,不变性是一件好事,但这些问题似乎与可扩展性有些正交.那么,为什么不变性是使类成为 final 的一个很好的理由?
'Effective Java'一书中对此的解释
考虑 Java 中的 BigDecimal
和 BigInteger
类.
人们并未广泛理解不可变类必须是有效的最终类当 BigInteger
和 BigDecimal
被写入时,所以它们的所有方法都可能是被覆盖.不幸的是,这无法在事后纠正,同时保持向后兼容性.
如果您编写的类的安全性取决于来自不受信任客户端的 BigInteger 或 BigDecimal 参数的不变性,则必须检查该参数是否是真实的"BigInteger 或 BigDecimal,而不是不可信子类的实例.如果是后者,您必须在假设它可能可变的情况下防御性地复制它.
public static BigInteger safeInstance(BigInteger val) {如果 (val.getClass() != BigInteger.class)返回新的 BigInteger(val.toByteArray());返回值;}
如果你允许子类化,它可能会破坏不可变对象的纯度".
It says in this article that:
I'm a bit puzzled by this... I understand that immutability is a good thing from the POV of thread-safety and simplicity, but it seems that these concerns are somewhat orthogonal to extensibility. So, why is immutability a good reason for making a class final?
The explanation for this is given in the book 'Effective Java'
Consider BigDecimal
and BigInteger
classes in Java .
It was not widely understood that immutable classes had to be effectively finalwhen BigInteger
and BigDecimal
were written, so all of their methods may beoverridden. Unfortunately, this could not be corrected after the fact while preserving backward compatibility.
If you write a class whose security depends on the immutability of a BigInteger or BigDecimal argument from an un-trusted client, you must check to see that the argument is a "real" BigInteger or BigDecimal, rather than an instance of an un trusted subclass. If it is the latter, you must defensively copy it under the assumption that it might be mutable.
public static BigInteger safeInstance(BigInteger val) {
if (val.getClass() != BigInteger.class)
return new BigInteger(val.toByteArray());
return val;
}
If you allow sub classing, it might break the "purity" of the immutable object.
这篇关于不可变类应该是最终的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!