Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'final' modifier on a class in Java

I have a quick and simple question. I have a habit of making every class 'final' unless of course, it needs to be extended by another.

Is this a bad habit? A good habit? Does it even matter? I understand the effect of the modifier to a class.

Thanks a lot in advance!

Edit: Here is an example code. This class will not be extended by any other classes.

public final class Application {

    /**
     * Starts the application.
     * 
     * @param arguments arguments provided from command-line
     */
    public static void main(String[] arguments) {
        LaunchUtilities util = new LaunchUtilities(new EventHandler());

        try {
            util.addListener(43594);
        } catch (IOException ioe) {
            Logger.getLogger(Application.class.getName()).log(Level.SEVERE, "Could not bind a port to a listener!", ioe);
        }

        util.start();
    }
}
like image 972
Martin Tuskevicius Avatar asked Aug 01 '11 23:08

Martin Tuskevicius


People also ask

What is use of final modifier in Java?

The final keyword is a non-access modifier used for classes, attributes and methods, which makes them non-changeable (impossible to inherit or override). The final keyword is useful when you want a variable to always store the same value, like PI (3.14159...). The final keyword is called a "modifier".

Can we use final with class in Java?

The main purpose of using a class being declared as final is to prevent the class from being subclassed. If a class is marked as final then no class can inherit any feature from the final class. You cannot extend a final class. If you try it gives you a compile time error.

Can final be used with class?

A class can be made final by using the final keyword. The final class cannot be inherited and so the final keyword is commonly used with a class to prevent inheritance.

When should you use the final modifier for a method?

When the final keyword is used with a method that cannot be overridden in Java, which means you cannot override the logic of the method in the subclass. This is also done to protect the original logic of the method. It's a compromise between making the whole class final or just making one method final.


2 Answers

Programmers (even Java gurus) disagree on this.

Josh Bloch, who designed the Java Collections library, java.Math, assert, and is chief java architect at Google (or was before they hired Gosling) has a section of his book "Effective Java" devoted to this issue. I go with what he has to say:

Item 17: Design and document for inheritance or else prohibit it

He points out that subclassing classes that were not designed for it often leads to disaster.

Furthermore, designing for inheritance is expensive.

  1. It puts major limits on what your class can do
  2. You have to write more documentation so that sub class authors know how public methods are used internally by the class
  3. You must test it. This requires testing writing subclasses

You can always change your mind and make something non-final. You cant make something final that use to be not final.

Read "Effective Java" it makes this argument much more compellingly. It will also make you a better programmer.

like image 116
Philip JF Avatar answered Sep 27 '22 18:09

Philip JF


I'm going to say bad habit, for the following reasons:

  • You have not specified any particular need for the class to be final.
  • You are violating the open/closed principle. Classes should be open for extension, but closed for modification.
  • Finalized classes can be difficult to test with mocking frameworks.

For example:

public static void main(String[] args) {
    final Fruit mockFruit = Mockito.mock(Fruit.class);
}

private static final class Fruit {

}

...will yield...

Exception in thread "main" org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class org.foo.Foo$Fruit
Mockito cannot mock/spy following:
  - final classes
  - anonymous classes
  - primitive types

Of course, there are valid scenarios for finalizing classes. For example, your class is immutable.

like image 44
hoipolloi Avatar answered Sep 27 '22 17:09

hoipolloi