1

I am creating a very simple class called Catalog. It will be an immutable class and have an id and name field.

Out of habit, since I am not going to explicitly document this thing for extensibility, I put the final modifier on the class. However I'm wondering that since this is such a simple value class, would it hurt to leave the final modifier off in case someone in the future decides they could use it?

  • 2
    Is this class part of a public API, and used by code on which you have no control? If so, then you should definitely think if it makes sense or not to extend the class. If not, then leave it final, and ask yourself if it's a good idea to make it non-final when you feel the need to extend the class. – JB Nizet Sep 15 '14 at 17:50
  • 2
    Take a look at http://stackoverflow.com/questions/218744/good-reasons-to-prohibit-inheritance-in-java. The top answer has a good summary for extensibility. – mkobit Sep 15 '14 at 17:51
  • If the [reasons are known](http://stackoverflow.com/questions/218744/good-reasons-to-prohibit-inheritance-in-java), there is no need to discuss it. That can only end in opinion based positings. – Holger Sep 15 '14 at 18:01

3 Answers3

2

You said "it will be immutable", so make it final to ensure the class cannot be overridden

sol4me
  • 15,233
  • 5
  • 34
  • 34
1

In my opinion, it is good practice to make simple value types final. If you want to guarantee immutability, you actually have to do so. That's also (partially) why String, Integer, etc are all final.

If your class is not final, somebody could extend it by adding methods that mutate it. A client who is passed an instance of the extended type (upcasted to your type) would falsely believe to deal with an immutable object when it actually isn't.

In my own code, I actually go a little further and make almost any class final if I didn't design it with extensibility explicitly in mind. If you want to support extension, consider providing an abstract class or an interface. This is also in line with the abstract, final or empty rule for methods.

Update: Why does immutability require a class to be final? Of course, there are other ways to ensure a particular attribute of an object is not changed.

Consider for example a RGBColor class with three attributes red, green and blue of type byte. We make all three final and set them in the constructor once for all time. (We can additionally make them private and add appropriate getter methods but that's not important for the sake of this discussion.) Of course, we override the equals method to return true if and only if the compared object is an instance of RGBColor with the same red, green and blue values.

This looks innocent but what if somebody decides to extend our class to a RGBAColor class by adding an alpha attribute? Naturally, the extender would desire to override equals to also take into account the alpha value. Suppose our extender also isn't very careful about immutability and thus makes alpha non-final and supplies a setter for it.

Now, if we are given an object of type RGBColor, we cannot safely assume that if it compared equal to another one, it will still do so a minute from now. We could have prevented this (particular problem) by also declaring equals as final in our RGBColor class. But then, we could have equally well made the entire class final because extending a value type without the possibility to extend the notion of equality is close to useless. (Thre are other problems with overriding equals such as it not being symmetric. I generally feel not too comfortable about it.)

5gon12eder
  • 24,280
  • 5
  • 45
  • 92
  • So even though my fields are private, a subclass could overwrite those values? I don't see how immutability is broken for the actual values. However I see that overridding one of the super class's method could return a value other than the one set in the constructor so that from a clients point of view the class is mutable. Can you elaborate please. – zztonedefzz Sep 16 '14 at 18:56
1

Yes it could hurt to leave off the final modifier. By omitting it the people who use your class can't trust that it's immutable, and therefore they can't take advantage of the benefits of immutable objects, for example thread safety.

Dave C
  • 928
  • 6
  • 12