What is the point of "final class" in Java?

JavaFinal

Java Problem Overview


I am reading a book about Java and it says that you can declare the whole class as final. I cannot think of anything where I'd use this.

I am just new to programming and I am wondering if programmers actually use this on their programs. If they do, when do they use it so I can understand it better and know when to use it.

If Java is object oriented, and you declare a class final, doesn't it stop the idea of class having the characteristics of objects?

Java Solutions


Solution 1 - Java

First of all, I recommend this article: Java: When to create a final class


> If they do, when do they use it so I can understand it better and know when to use it.

A final class is simply a class that can't be extended.

(It does not mean that all references to objects of the class would act as if they were declared as final.)

When it's useful to declare a class as final is covered in the answers of this question:

> If Java is object oriented, and you declare a class final, doesn't it stop the idea of class having the characteristics of objects?

In some sense yes.

By marking a class as final you disable a powerful and flexible feature of the language for that part of the code. Some classes however, should not (and in certain cases can not) be designed to take subclassing into account in a good way. In these cases it makes sense to mark the class as final, even though it limits OOP. (Remember however that a final class can still extend another non-final class.)

Solution 2 - Java

In Java, items with the final modifier cannot be changed!

This includes final classes, final variables, and final methods:

  • A final class cannot be extended by any other class
  • A final variable cannot be reassigned another value
  • A final method cannot be overridden

Solution 3 - Java

One scenario where final is important, when you want to prevent inheritance of a class, for security reasons. This allows you to make sure that code you are running cannot be overridden by someone.

Another scenario is for optimization: I seem to remember that the Java compiler inlines some function calls from final classes. So, if you call a.x() and a is declared final, we know at compile-time what the code will be and can inline into the calling function. I have no idea whether this is actually done, but with final it is a possibility.

Solution 4 - Java

The best example is

> public final class String

which is an immutable class and cannot be extended. Of course, there is more than just making the class final to be immutable.

Solution 5 - Java

If you imagine the class hierarchy as a tree (as it is in Java), abstract classes can only be branches and final classes are those that can only be leafs. Classes that fall into neither of those categories can be both branches and leafs.

There's no violation of OO principles here, final is simply providing a nice symmetry.

In practice you want to use final if you want your objects to be immutable or if you're writing an API, to signal to the users of the API that the class is just not intended for extension.

Solution 6 - Java

Relevant reading: The Open-Closed Principle by Bob Martin.

Key quote:

> Software Entities (Classes, Modules, > Functions, etc.) should be open for > Extension, but closed for > Modification.

The final keyword is the means to enforce this in Java, whether it's used on methods or on classes.

Solution 7 - Java

The keyword final itself means something is final and is not supposed to be modified in any way. If a class if marked final then it can not be extended or sub-classed. But the question is why do we mark a class final? IMO there are various reasons:

  1. Standardization: Some classes perform standard functions and they are not meant to be modified e.g. classes performing various functions related to string manipulations or mathematical functions etc.
  2. Security reasons: Sometimes we write classes which perform various authentication and password related functions and we do not want them to be altered by anyone else.

I have heard that marking class final improves efficiency but frankly I could not find this argument to carry much weight.

> If Java is object oriented, and you declare a class final, doesn't it > stop the idea of class having the characteristics of objects?

Perhaps yes, but sometimes that is the intended purpose. Sometimes we do that to achieve bigger benefits of security etc. by sacrificing the ability of this class to be extended. But a final class can still extend one class if it needs to.

On a side note we should prefer composition over inheritance and final keyword actually helps in enforcing this principle.

Solution 8 - Java

final class can avoid breaking the public API when you add new methods

Suppose that on version 1 of your Base class you do:

public class Base {}

and a client does:

class Derived extends Base {
    public int method() { return 1; }
}

Then if in version 2 you want to add a method method to Base:

class Base {
    public String method() { return null; }
}

it would break the client code.

If we had used final class Base instead, the client wouldn't have been able to inherit, and the method addition wouldn't break the API.

Solution 9 - Java

A final class is a class that can't be extended. Also methods could be declared as final to indicate that cannot be overridden by subclasses.

Preventing the class from being subclassed could be particularly useful if you write APIs or libraries and want to avoid being extended to alter base behaviour.

Solution 10 - Java

In java final keyword uses for below occasions.

  1. Final Variables
  2. Final Methods
  3. Final Classes

> In java final variables can't reassign, final classes can't extends and final methods can't override.

Solution 11 - Java

Be careful when you make a class "final". Because if you want to write an unit test for a final class, you cannot subclass this final class in order to use the dependency-breaking technique "Subclass and Override Method" described in Michael C. Feathers' book "Working Effectively with Legacy Code". In this book, Feathers said, "Seriously, it is easy to believe that sealed and final are a wrong-headed mistake, that they should never have been added to programming languages. But the real fault lies with us. When we depend directly on libraries that are out of our control, we are just asking for trouble."

Solution 12 - Java

If the class is marked final, it means that the class' structure can't be modified by anything external. Where this is the most visible is when you're doing traditional polymorphic inheritance, basically class B extends A just won't work. It's basically a way to protect some parts of your code (to extent).

To clarify, marking class final doesn't mark its fields as final and as such doesn't protect the object properties but the actual class structure instead.

Solution 13 - Java

TO ADDRESS THE FINAL CLASS PROBLEM:

There are two ways to make a class final. The first is to use the keyword final in the class declaration:

public final class SomeClass {
  //  . . . Class contents
}

The second way to make a class final is to declare all of its constructors as private:

public class SomeClass {
  public final static SOME_INSTANCE = new SomeClass(5);
  private SomeClass(final int value) {
  }

Marking it final saves you the trouble if finding out that it is actual a final, to demonstrate look at this Test class. looks public at first glance.

public class Test{
  private Test(Class beanClass, Class stopClass, int flags)
    throws Exception{
    //  . . . snip . . . 
  }
}

Unfortunately, since the only constructor of the class is private, it is impossible to extend this class. In the case of the Test class, there is no reason that the class should be final. The Test class is a good example of how implicit final classes can cause problems.

So you should mark it final when you implicitly make a class final by making it's constructor private.

Solution 14 - Java

One advantage of keeping a class as final :-

String class is kept final so that no one can override its methods and change the functionality. e.g no one can change functionality of length() method. It will always return length of a string.

Developer of this class wanted no one to change functionality of this class, so he kept it as final.

Solution 15 - Java

Yes, sometimes you may want this though, either for security or speed reasons. It's done also in C++. It may not be that applicable for programs, but moreso for frameworks. http://www.glenmccl.com/perfj_025.htm

Solution 16 - Java

think of FINAL as the "End of the line" - that guy cannot produce offspring anymore. So when you see it this way, there are ton of real world scenarios that you will come across that requires you to flag an 'end of line' marker to the class. It is Domain Driven Design - if your domain demands that a given ENTITY (class) cannot create sub-classes, then mark it as FINAL.

I should note that there is nothing stopping you from inheriting a "should be tagged as final" class. But that is generally classified as "abuse of inheritance", and done because most often you would like to inherit some function from the base class in your class.

The best approach is to look at the domain and let it dictate your design decisions.

Solution 17 - Java

The other answers have focused on what final class tells the compiler: do not allow another class to declare it extends this class, and why that is desirable.

But the compiler is not the only reader of the phrase final class. Every programmer who reads the source code also reads that. It can aid rapid program comprehension.

In general, if a programmer sees Thing thing = that.someMethod(...); and the programmer wants to understand the subsequent behaviour of the object accessed through the thing object-reference, the programmer must consider the Thing class hierarchy: potentially many types, scattered over many packages. But if the programmer knows, or reads, final class Thing, they instantly know that they do not need to search for and study so many Java files, because there are no derived classes: they need study only Thing.java and, perhaps, it's base classes.

Solution 18 - Java

As above told, if you want no one can change the functionality of the method then you can declare it as final.

Example: Application server file path for download/upload, splitting string based on offset, such methods you can declare it Final so that these method functions will not be altered. And if you want such final methods in a separate class, then define that class as Final class. So Final class will have all final methods, where as Final method can be declared and defined in non-final class.

Solution 19 - Java

Let's say you have an Employee class that has a method greet. When the greet method is called it simply prints Hello everyone!. So that is the expected behavior of greet method

public class Employee {

	void greet() {
		System.out.println("Hello everyone!");
	}
}

Now, let GrumpyEmployee subclass Employee and override greet method as shown below.

public class GrumpyEmployee extends Employee {

	@Override
	void greet() {
		System.out.println("Get lost!");
	}
}

Now in the below code have a look at the sayHello method. It takes Employee instance as a parameter and calls the greet method hoping that it would say Hello everyone! But what we get is Get lost!. This change in behavior is because of Employee grumpyEmployee = new GrumpyEmployee();

public class TestFinal {
	static Employee grumpyEmployee = new GrumpyEmployee();
	
	public static void main(String[] args) {
		TestFinal testFinal = new TestFinal();
		testFinal.sayHello(grumpyEmployee);
	}
	
	private void sayHello(Employee employee) {
		employee.greet(); //Here you would expect a warm greeting, but what you get is "Get lost!"
	}
}

This situation can be avoided if the Employee class was made final. Just imagine the amount of chaos a cheeky programmer could cause if String Class was not declared as final.

Solution 20 - Java

Final class cannot be extended further. If we do not need to make a class inheritable in java,we can use this approach.

If we just need to make particular methods in a class not to be overridden, we just can put final keyword in front of them. There the class is still inheritable.

Solution 21 - Java

Final classes cannot be extended. So if you want a class to behave a certain way and don't someone to override the methods (with possibly less efficient and more malicious code), you can declare the whole class as final or specific methods which you don't want to be changed.

Since declaring a class does not prevent a class from being instantiated, it does not mean it will stop the class from having the characteristics of an object. It's just that you will have to stick to the methods just the way they are declared in the class.

Solution 22 - Java

Android Looper class is a good practical example of this. http://developer.android.com/reference/android/os/Looper.html

The Looper class provides certain functionality which is NOT intended to be overridden by any other class. Hence, no sub-class here.

Solution 23 - Java

I know only one actual use case: generated classes

Among the use cases of generated classes, I know one: dependency inject e.g. https://github.com/google/dagger

Solution 24 - Java

Object Orientation is not about inheritance, it is about encapsulation. And inheritance breaks encapsulation.

Declaring a class final makes perfect sense in a lot of cases. Any object representing a “value” like a color or an amount of money could be final. They stand on their own.

If you are writing libraries, make your classes final unless you explicitly indent them to be derived. Otherwise, people may derive your classes and override methods, breaking your assumptions / invariants. This may have security implications as well.

Joshua Bloch in “Effective Java” recommends designing explicitly for inheritance or prohibiting it and he notes that designing for inheritance is not that easy.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnewbieView Question on Stackoverflow
Solution 1 - JavaaioobeView Answer on Stackoverflow
Solution 2 - JavaandyqeeView Answer on Stackoverflow
Solution 3 - JavaShay RojanskyView Answer on Stackoverflow
Solution 4 - JavajavadeveloperView Answer on Stackoverflow
Solution 5 - JavabiziclopView Answer on Stackoverflow
Solution 6 - JavaSean Patrick FloydView Answer on Stackoverflow
Solution 7 - Javaakhil_mittalView Answer on Stackoverflow
Solution 8 - JavaCiro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 9 - JavaJuanZeView Answer on Stackoverflow
Solution 10 - JavaKavinda PushpithaView Answer on Stackoverflow
Solution 11 - JavaBen WuView Answer on Stackoverflow
Solution 12 - JavaEskoView Answer on Stackoverflow
Solution 13 - Javamel3kingsView Answer on Stackoverflow
Solution 14 - JavaRahulView Answer on Stackoverflow
Solution 15 - JavaJamesView Answer on Stackoverflow
Solution 16 - JavaKingzView Answer on Stackoverflow
Solution 17 - JavaRaedwaldView Answer on Stackoverflow
Solution 18 - JavalokView Answer on Stackoverflow
Solution 19 - JavaAndyView Answer on Stackoverflow
Solution 20 - JavaG. RavenView Answer on Stackoverflow
Solution 21 - JavaskhaapioloirView Answer on Stackoverflow
Solution 22 - JavajaamitView Answer on Stackoverflow
Solution 23 - JavaericnView Answer on Stackoverflow
Solution 24 - JavaWilhem MeignanView Answer on Stackoverflow