简体   繁体   中英

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'?

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.

If anyone knows any such classes, please provide examples.

java.awt.Dimension isn't final or immutable and should have been. Anything that returns a Dimension (eg a Window object) needs to make defensive copies to prevent callers from doing nasty things.

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.

In particular, all of their methods can be overriden. That enables you to create a broken BigDecimal , for example:

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.

To paraphrase Effective Java:

  • Design and document for inheritance or else prohibit it
  • Classes should be immutable unless there's a very good reason to make them mutable

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 .

There are good reasons to complain about this.

Then there is BitSet , BitInteger etc. which could be made 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.

To pick on a particular class: BitSet . It is not final , yet you cannot extend it to add a bit shift operation. They might as well have made it final then, or allow us to add such functionality.

The Date class leaps out. 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. 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 .

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. For instance java.util.String is final for that very reason. So are many others. Some classes w/ private c-tor are declared final (Math, StrictMath) but it doesn't matter in such a case.

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. 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() .

I believe java.util.Arrays and java.util.Collections should be declared final.

Here is why:

  1. They contain only static members and a private constructor .
  2. The private constructor prevents those classes from being extended.

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.

Additionally, java.lang.Math (another so-called utility class ) has the same structure and it is also declared final .

Check the String class which is final and probably should had been your answer in the interview.

Check the docs.

http://docs.oracle.com/javase/7/docs/api/java/lang/String.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM