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:

  • Good reasons to prohibit inheritance in Java?

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

Answer from aioobe on Stack Overflow
🌐
Upgrad
upgrad.com › home › tutorials › software & tech › final class in java
Final Class in Java | Meaning, Method & Example Explained
June 24, 2025 - Final Class in Java: A tutorial on creating classes that cannot be extended or overridden, enhancing code security and design integrity.
People also ask

Can a final class in Java have final methods?
Yes, a final class in Java can contain both final and non-final methods. However, since the class itself can’t be extended, marking its methods as final has limited impact beyond internal clarity or intent. Yes, a final class in Java can contain both final and non-final methods. However, since the class itself can’t be extended, marking its methods as final has limited impact beyond internal clarity or intent.
🌐
upgrad.com
upgrad.com › home › tutorials › software & tech › final class in java
Final Class in Java | Meaning, Method & Example Explained
Can you create a final variable in a final class in Java?
Yes, you can declare final variables inside a final class. Final variables are constants, and their values cannot be changed once assigned. They’re commonly used for defining fixed configurations or constants in Java. Yes, you can declare final variables inside a final class . Final variables are constants, and their values cannot be changed once assigned. They’re commonly used for defining fixed configurations or constants in Java.
🌐
upgrad.com
upgrad.com › home › tutorials › software & tech › final class in java
Final Class in Java | Meaning, Method & Example Explained
What is the difference between final class and final method in Java?
A final class can’t be extended, while a final method can’t be overridden. Both enforce restrictions on inheritance but at different levels—class-level restriction versus method-level customization control within subclassing. A final class can’t be extended, while a final method can’t be overridden. Both enforce restrictions on inheritance but at different levels—class-level restriction versus method-level customization control within subclassing.
🌐
upgrad.com
upgrad.com › home › tutorials › software & tech › final class in java
Final Class in Java | Meaning, Method & Example Explained
🌐
GeeksforGeeks
geeksforgeeks.org › java › final-keyword-in-java
final Keyword in Java - GeeksforGeeks
The final keyword is a non-access modifier used to restrict modification. It applies to variables (value cannot change) methods (cannot be overridden) and classes (cannot be extended).
Published   July 22, 2014
🌐
Oracle
docs.oracle.com › javase › tutorial › java › IandI › final.html
Writing Final Classes and Methods (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance)
You use the final keyword in a method declaration to indicate that the method cannot be overridden by subclasses. The Object class does this—a number of its methods are final.
🌐
Scaler
scaler.com › topics › final-class-in-java
Final Class in Java | Scaler Topics
July 21, 2022 - As the name suggests, the Final Class in Java uses the final keyword for its declaration. The final keyword in Java restricts the user; similarly, the final class means that the class cannot be extended. We can only create a final class if it is complete, which means it cannot be an abstract class.
🌐
Baeldung
baeldung.com › home › java › core java › the “final” keyword in java
The "final" Keyword in Java | Baeldung
June 14, 2025 - Consider the situation if we can extend the String class, override any of its methods, and substitute all the String instances with the instances of our specific String subclass. The result of the operations over String objects will then become unpredictable. And given that the String class is used everywhere, it’s unacceptable. That’s why the String class is marked as final.
🌐
Wikipedia
en.wikipedia.org › wiki › Final_(Java)
final (Java) - Wikipedia
October 29, 2025 - When an anonymous inner class is defined within the body of a method, all variables declared final in the scope of that method are accessible from within the inner class. For scalar values, once it has been assigned, the value of the final variable cannot change. For object values, the reference cannot change. This allows the Java compiler to "capture" the value of the variable at run-time and store a copy as a field in the inner class.
Find elsewhere
🌐
DataCamp
datacamp.com › doc › java › final
final Keyword in Java: Usage & Examples
The final keyword in Java is a non-access modifier that can be applied to variables, methods, and classes. It is used to restrict the user from further modifying the entity to which it is applied.
🌐
W3Schools
w3schools.com › java › ref_keyword_final.asp
Java final Keyword
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 ...
🌐
Whitman College
whitman.edu › mathematics › java_tutorial › java › javaOO › final.html
Writing Final Classes and Methods
You can declare that your class is final; that is, that your class cannot be subclassed. There are (at least) two reasons why you might want to do this: security reasons and design reasons. Security: One mechanism that hackers use to subvert systems is to create subclasses of a class and then ...
🌐
Reddit
reddit.com › r/java › why would anyone declare a class 'final'?
r/java on Reddit: Why would anyone declare a class 'final'?
March 10, 2010 -

Okay so I'm fairly new to Java programming but I've been a programmer for a long time (> 10 years). I'm currently writing an application which involves building some strings. I find myself doing this a lot:

String lineTerminator = System.getProperty("line.separator");
StringBuilder sb = new StringBuilder();
...
sb.append("blah blah blah").append(lineTerminator);

So I thought I'll just extend the Stringbuilder class and add a method:

public void appendLine(String s);

with the obvious semantics. But I find I can't do that because the StringBuilder class is declared as 'final' why?

I've vaguely googled a bit for this but the answer generally seems to be: "You would make a class Final in Java if you do not want anybody to inherit the features of your class. " and "You don't want anybody to inherit from your class because that code would not work" but I can't seem to get a reasonable explanation for why it might not work. I understand why one might declare a method as 'final' but not a class.

🌐
Programiz
programiz.com › java-programming › final-keyword
Java final keyword (With examples)
Once any entity (variable, method or class) is declared final, it can be assigned only once. That is, the final variable cannot be reinitialized with another value ... In Java, we cannot change the value of a final variable.
🌐
TutorialsPoint
tutorialspoint.com › What-are-final-classes-in-Java
What are final classes in Java?
The final modifier for finalizing the implementations of classes, methods, and variables. 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 c
🌐
Blog
cipherschools.com › home › others › what are final class in java with examples
What are Final Class in Java with Examples - Blog | Cipherschools: The Best Learning Platform
September 18, 2025 - Yes, final classes can have static methods. The “final” keyword only restricts subclassing, not the inclusion of static methods. ... No, the “final” keyword in Java ensures that the value assigned to a final variable cannot be changed after initialization, including being set to null.
Top answer
1 of 10
137

final expresses intent. It tells the user of a class, method or variable "This element is not supposed to change, and if you want to change it, you haven't understood the existing design."

This is important because program architecture would be really, really hard if you had to anticipate that every class and every method you ever write might be changed to do something completely different by a subclass. It is much better to decide up-front which elements are supposed to be changeable and which aren't, and to enforce the unchangeablility via final.

You could also do this via comments and architecture documents, but it is always better to let the compiler enforce things that it can than to hope that future users will read and obey the documentation.

2 of 10
60

It avoids the Fragile Base Class Problem. Every class comes with a set of implicit or explicit guarantees and invariants. The Liskov Substitution Principle mandates that all subtypes of that class must also provide all these guarantees. However, it is really easy to violate this if we don't use final. For example, let's have a password checker:

public class PasswordChecker {
  public boolean passwordIsOk(String password) {
    return password == "s3cret";
  }
}

If we allow that class to be overridden, one implementation could lock out everyone, another might give everyone access:

public class OpenDoor extends PasswordChecker {
  public boolean passwordIsOk(String password) {
    return true;
  }
}

This is usually not OK, since the subclasses now have behaviour that is very incompatible to the original. If we really intend the class to be extended with other behaviour, a Chain of Responsibility would be better:

PasswordChecker passwordChecker =
  new DefaultPasswordChecker(null);
// or:
PasswordChecker passwordChecker =
  new OpenDoor(null);
// or:
PasswordChecker passwordChecker =
 new DefaultPasswordChecker(
   new OpenDoor(null)
 );

public interface PasswordChecker {
  boolean passwordIsOk(String password);
}

public final class DefaultPasswordChecker implements PasswordChecker {
  private PasswordChecker next;

  public DefaultPasswordChecker(PasswordChecker next) {
    this.next = next;
  }

  @Override
  public boolean passwordIsOk(String password) {
    if ("s3cret".equals(password)) return true;
    if (next != null) return next.passwordIsOk(password);
    return false;
  }
}

public final class OpenDoor implements PasswordChecker {
  private PasswordChecker next;

  public OpenDoor(PasswordChecker next) {
    this.next = next;
  }

  @Override
  public boolean passwordIsOk(String password) {
    return true;
  }
}

The problem becomes more apparent when more a complicated class calls its own methods, and those methods can be overridden. I sometimes encounter this when pretty-printing a data structure or writing HTML. Each method is responsible for some widget.

public class Page {
  ...;

  @Override
  public String toString() {
    PrintWriter out = ...;
    out.print("<!DOCTYPE html>");
    out.print("<html>");

    out.print("<head>");
    out.print("</head>");

    out.print("<body>");
    writeHeader(out);
    writeMainContent(out);
    writeMainFooter(out);
    out.print("</body>");

    out.print("</html>");
    ...
  }

  void writeMainContent(PrintWriter out) {
    out.print("<div class='article'>");
    out.print(htmlEscapedContent);
    out.print("</div>");
  }

  ...
}

I now create a subclass that adds a bit more styling:

class SpiffyPage extends Page {
  ...;


  @Override
  void writeMainContent(PrintWriter out) {
    out.print("<div class='row'>");

    out.print("<div class='col-md-8'>");
    super.writeMainContent(out);
    out.print("</div>");

    out.print("<div class='col-md-4'>");
    out.print("<h4>About the Author</h4>");
    out.print(htmlEscapedAuthorInfo);
    out.print("</div>");

    out.print("</div>");
  }
}

Now ignoring for a moment that this is not a very good way to generate HTML pages, what happens if I want to change the layout yet again? I'd have to create a SpiffyPage subclass that somehow wraps that content. What we can see here is an accidental application of the template method pattern. Template methods are well-defined extension points in a base class that are intended to be overridden.

And what happens if the base class changes? If the HTML contents change too much, this could break the layout provided by the subclasses. It is therefore not really safe to change the base class afterwards. This is not apparent if all your classes are in the same project, but very noticeable if the base class is part of some published software that other people build upon.

If this extension strategy was intended, we could have allowed the user to swap out the way how each part is generated. Either, there could be a Strategy for each block that can be provided externally. Or, we could nest Decorators. This would be equivalent to the above code, but far more explicit and far more flexible:

Page page = ...;
page.decorateLayout(current -> new SpiffyPageDecorator(current));
print(page.toString());

public interface PageLayout {
  void writePage(PrintWriter out, PageLayout top);
  void writeMainContent(PrintWriter out, PageLayout top);
  ...
}

public final class Page {
  private PageLayout layout = new DefaultPageLayout();

  public void decorateLayout(Function<PageLayout, PageLayout> wrapper) {
    layout = wrapper.apply(layout);
  }

  ...
  @Override public String toString() {
    PrintWriter out = ...;
    layout.writePage(out, layout);
    ...
  }
}

public final class DefaultPageLayout implements PageLayout {
  @Override public void writeLayout(PrintWriter out, PageLayout top) {
    out.print("<!DOCTYPE html>");
    out.print("<html>");

    out.print("<head>");
    out.print("</head>");

    out.print("<body>");
    top.writeHeader(out, top);
    top.writeMainContent(out, top);
    top.writeMainFooter(out, top);
    out.print("</body>");

    out.print("</html>");
  }

  @Override public void writeMainContent(PrintWriter out, PageLayout top) {
    ... /* as above*/
  }
}

public final class SpiffyPageDecorator implements PageLayout {
  private PageLayout inner;

  public SpiffyPageDecorator(PageLayout inner) {
    this.inner = inner;
  }

  @Override
  void writePage(PrintWriter out, PageLayout top) {
    inner.writePage(out, top);
  }

  @Override
  void writeMainContent(PrintWriter out, PageLayout top) {
    ...
    inner.writeMainContent(out, top);
    ...
  }
}

(The additional top parameter is necessary to make sure that the calls to writeMainContent go through the top of the decorator chain. This emulates a feature of subclassing called open recursion.)

If we have multiple decorators, we can now mix them more freely.

Far more often than the desire to slightly adapt existing functionality is the desire to reuse some part of an existing class. I have seen a case where someone wanted a class where you could add items and iterate over all of them. The correct solution would have been to:

final class Thingies implements Iterable<Thing> {
  private ArrayList<Thing> thingList = new ArrayList<>();

  @Override public Iterator<Thing> iterator() {
    return thingList.iterator();
  }

  public void add(Thing thing) {
    thingList.add(thing);
  }

  ... // custom methods
}

Instead, they created a subclass:

class Thingies extends ArrayList<Thing> {
  ... // custom methods
}

This suddenly means that the whole interface of ArrayList has become part of our interface. Users can remove() things, or get() things at specific indices. This was intended that way? OK. But often, we don't carefully think through all consequences.

It is therefore advisable to

  • never extend a class without careful thought.
  • always mark your classes as final except if you intend for any method to be overridden.
  • create interfaces where you want to swap out an implementation, e.g. for unit testing.

There are many examples where this “rule” has to be broken, but it usually guides you to a good, flexible design, and avoids bugs due to unintended changes in base classes (or unintended uses of the subclass as an instance of the base class).

Some languages have stricter enforcement mechanisms:

  • All methods are final by default and have to be marked explicitly as virtual
  • They provide private inheritance that doesn't inherit the interface but only the implementation.
  • They require base class methods to be marked as virtual, and require all overrides to be marked as well. This avoids problems where a subclass defined a new method, but a method with the same signature was later added to the base class but not intended as virtual.
🌐
Quora
quora.com › What-is-final-class-in-Java
What is final class in Java? - Quora
Answer (1 of 7): If a class is declared as final, then it becomes final class. A final class cannot extend to another class. So we cannot access variables, methods present inside a final class to other class.
🌐
PrepBytes
prepbytes.com › home › java › what is final class in java?
What is Final Class in Java?
April 26, 2023 - In Java, the "final" keyword is used to indicate that a variable, method, or class can only be assigned a value once and cannot be changed thereafter. The final keyword is used to limit access and modification by the user.
🌐
Javatpoint
javatpoint.com › final-keyword
Final Keyword In Java
final keyword. The final is a keyword in java. Final can be variable, method, class or parameter. Let's see what are there usage.
🌐
Medium
medium.com › @ByteCodeBlogger › javas-final-frontier-creating-immutable-and-unextendable-classes-in-java-9fc253a40c58
Java’s Final Frontier: Creating Immutable and Unextendable Classes in Java | by Full Stack Developer | Medium
July 23, 2024 - Creating a final class in Java is straightforward: you simply use the final keyword in the class declaration. A final class cannot be extended (subclassed).