[英]Final classes in Java which shouldn't be final or vice versa?
I was asked this question in an interview recently: 我最近在一次采访中被问到这个问题:
Can you name any class in the Java API that is final that shouldn't be or one that isn't and should be'? 你可以在Java API中命名任何不应该是最终的类,或者那个不应该且应该是'的类吗?
I couldn't think of any. 我什么都想不到。 The question implies that I should know all the API classes like the back of my hand, which I personally wouldn't expect any Java developer to know. 这个问题意味着我应该知道所有的API类,比如我的手,我个人不希望任何Java开发人员知道。
If anyone knows any such classes, please provide examples. 如果有人知道任何此类课程,请提供示例。
java.awt.Dimension
isn't final or immutable and should have been. java.awt.Dimension
不是final或immutable,应该是。 Anything that returns a Dimension (eg a Window object) needs to make defensive copies to prevent callers from doing nasty things. 任何返回Dimension(例如Window对象)的东西都需要制作防御性副本以防止调用者做出讨厌的事情。
The first examples that come to mind are some of the non-final Number subclasses, such as BigDecimal
and BigInteger
, which should probably have been final. 我想到的第一个例子是一些非最终的Number子类,比如BigDecimal
和BigInteger
,它们应该是最终的。
In particular, all of their methods can be overriden. 特别是,他们的所有方法都可以被覆盖。 That enables you to create a broken BigDecimal
, for example: 这使您可以创建一个损坏的BigDecimal
,例如:
public class BrokenBigDecimal extends BigDecimal {
public BigDecimal add(BigDecimal augend) {
return BigDecimal.ZERO;
}
}
That could create significant issues if you receive BigDecimal from an untrusted code for example. 如果您从不受信任的代码接收BigDecimal,那么这可能会产生重大问题。
To paraphrase Effective Java: 用有效的Java来解释:
In my opinion, your reply should have been that it is a matter of taste which classes should be final and which shouldn't. 在我看来,你的答复本应该是一个品味问题,哪些课程应该是最终的,哪些不应该。
There are good reasons to make Integer
, Double
and String
all final
. 有充分的理由使Integer
, Double
和String
都是final
。
There are good reasons to complain about this. 有充分理由抱怨这一点。
Then there is BitSet
, BitInteger
etc. which could be made final
. 然后有BitSet
, BitInteger
等可以做成final
。
There are a number of situations where classes are not final
, but they also cannot be extended reasonably, so they probably should have been made final. 在许多情况下,课程不是final
,但它们也不能合理地扩展,因此它们可能应该是最终的。
To pick on a particular class: BitSet
. 选择一个特定的类: BitSet
。 It is not final
, yet you cannot extend it to add a bit shift
operation. 它不是final
,但您无法扩展它以添加shift
操作。 They might as well have made it final
then, or allow us to add such functionality. 他们可能final
使它成为final
,或允许我们添加这样的功能。
The Date
class leaps out. Date
类跳出来了。 It is a mutable simple value class (essentially a wrapper around a long
), but a good heuristic is that simple value classes should be immutable. 它是一个可变的简单值类(本质上是一个long
的包装器),但一个好的启发式是简单的值类应该是不可变的。 Note also its numerous deprecated methods: more evidence that the design was botched. 还要注意其众多不赞成的方法:更多证据表明设计是拙劣的。 The mutability of the Date
is a source of bugs, requiring disciplined defensive copying . Date
的可变性是bug的来源,需要严格的防御性复制 。
one that isn't and should be 一个不是也应该是的
Most final classes in java are designed so due w/ security considerations in mind, overall there are relatively few final ones. java中的大多数最终类都是基于安全性考虑而设计的,总体而言,最终的类相对较少。 For instance java.util.String
is final for that very reason. 例如, java.util.String
是最终的,因为这个原因。 So are many others. 许多其他人也是如此。 Some classes w/ private c-tor are declared final (Math, StrictMath) but it doesn't matter in such a case. 有些私有c-tor的类被声明为final(Math,StrictMath),但在这种情况下并不重要。
Basically unless there are security issues involved I don't care if the class is final, yet you can always use non-public c-tor w/ some factory, effectively limiting the ability to subclass. 基本上除非涉及安全问题,否则我不关心课程是否是最终的,但你总是可以使用非公共c-tor w /某些工厂,有效地限制了子类的能力。 Usually that's my preferred way as it allows package-private subclassing. 通常这是我的首选方式,因为它允许包私有子类。
In short: I can't think of a final class that should not be, however there are some that could potentially have been. 简而言之:我不能想到一个不应该的最后一堂课,但是有一些可能已经存在。 For instance java.lang.Thread
being final might have not needed to protect vs malicious clone()
. 例如, java.lang.Thread
是final可能不需要保护vs恶意clone()
。
I believe java.util.Arrays
and java.util.Collections
should be declared final. 我相信java.util.Arrays
和java.util.Collections
应该声明为final。
Here is why: 原因如下:
So, those classes cannot be extended, but this fact is not visible in their public interface. 因此,这些类无法扩展,但这一事实在其公共接口中不可见。 Declaring them final
would expose it and clarify intent. 宣布他们final
将揭露它并澄清意图。
Additionally, java.lang.Math
(another so-called utility class ) has the same structure and it is also declared final
. 另外, java.lang.Math
(另一个所谓的实用程序类 )具有相同的结构,并且它也被声明为final
。
Check the String class which is final and probably should had been your answer in the interview. 检查最后的String类,可能应该是你在面试中的答案。
Check the docs. 检查文档。
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.