This is a favorite interview question. With this questions, the interviewer tries to find out how well you understand the behavior of objects with respect to constructors, methods, class variables (static variables) and instance variables.
Now a days interviewers are asking another favorite question what is effectively final from java 1.8.
I will explain in the end about this effectively final in java 1.8.

import java.util.ArrayList;
import java.util.List;

class Test {
    private final List foo; // comment-1    
    public Test() {
        foo = new ArrayList(); // comment-2
        foo.add("foo"); // Modification-1   comment-3
    }

    public void setFoo(List foo) {
       //this.foo = foo; Results in compile time error.
    }
}

In the above case, we have defined a constructor for 'Test' and gave it a 'setFoo' method.

About constructor: Constructor can be invoked only one time per object creation by using the new keyword. You cannot invoke constructor multiple times, because constructor are not designed to do so.

About method: A method can be invoked as many times as you want (Even never) and the compiler knows it.

Scenario 1

private final List foo;  // 1

foo is an instance variable. When we create Test class object then the instance variable foo, will be copied inside the object of Test class. If we assign final foo inside the constructor, then the compiler knows that the constructor will be invoked only once, so there is no problem assigning it inside the constructor.

If we assign final foo inside a method, the compiler knows that a method can be called multiple times, which means the value will have to be changed multiple times, which is not allowed for a final variable. So the compiler decides constructor is good choice! You can assign a value to a final variable only one time.

Scenario 2

private static final List foo = new ArrayList();

foo is now a static variable. When we create an instance of Test class, foo will not be copied to the object because foo is static. Now foo is not an independent property of each object. This is a property of Test class. But foo can be seen by multiple objects and if every object of Test which is created by using the new keyword which will ultimately invoke the Test constructor which changes the value of final static variable at the time of multiple object creation (Remember static foo is not copied in every object, but is shared between multiple objects.). To stop this, compiler knows final static cannot be initialized inside constructor and also cannot provide method to assign object to it. So we have to declare and define final List object at the same place at comment-1 in above program.

Scenario 3

t.foo.add("bar"); // Modification-2

Above Modification-2 is from your question. In the above case, you are not changing the first referenced object, but you are adding content inside foo which is allowed. Compiler complains if you try to assign a new ArrayList() to the foo reference variable.
Rule If you have initialized a final variable, then you cannot change it to refer to a different object. (In this case ArrayList)

final classes cannot be subclassed
final methods cannot be overridden. (This method is in superclass)
final methods can override. (Read this in grammatical way. This method is in a subclass)

Now let's see what is effectively final in java 1.8?

public class EffectivelyFinalDemo { //compile code with java 1.8
    public void process() {
        int thisValueIsFinalWithoutFinalKeyword = 10; //variable is effectively final
        
        //to work without final keyword you should not reassign value to above variable like given below 
        thisValueIsFinalWithoutFinalKeyword = getNewValue(); // delete this line when I tell you.
        
        class MethodLocalClass {
            public void innerMethod() {
                //below line is now showing compiler error like give below
                //Local variable thisValueIsFinalWithoutFinalKeyword defined in an enclosing scope must be final or effectively final
                System.out.println(thisValueIsFinalWithoutFinalKeyword); //on this line only final variables are allowed because this is method local class
                // if you want to test effectively final is working without final keyword then delete line which I told you to delete in above program.  
            }
        }
    }

    private int getNewValue() {
        return 0;
    }
}

Above program will throw error in java 1.7 or <1.8 if you do not use final keyword. Effectively final is a part of Method Local Inner classes. I know you would rarely use such effectively final in method local classes, but for interview we have to be prepared.

Answer from AmitG on Stack Overflow
Top answer
1 of 16
667

This is a favorite interview question. With this questions, the interviewer tries to find out how well you understand the behavior of objects with respect to constructors, methods, class variables (static variables) and instance variables.
Now a days interviewers are asking another favorite question what is effectively final from java 1.8.
I will explain in the end about this effectively final in java 1.8.

import java.util.ArrayList;
import java.util.List;

class Test {
    private final List foo; // comment-1    
    public Test() {
        foo = new ArrayList(); // comment-2
        foo.add("foo"); // Modification-1   comment-3
    }

    public void setFoo(List foo) {
       //this.foo = foo; Results in compile time error.
    }
}

In the above case, we have defined a constructor for 'Test' and gave it a 'setFoo' method.

About constructor: Constructor can be invoked only one time per object creation by using the new keyword. You cannot invoke constructor multiple times, because constructor are not designed to do so.

About method: A method can be invoked as many times as you want (Even never) and the compiler knows it.

Scenario 1

private final List foo;  // 1

foo is an instance variable. When we create Test class object then the instance variable foo, will be copied inside the object of Test class. If we assign final foo inside the constructor, then the compiler knows that the constructor will be invoked only once, so there is no problem assigning it inside the constructor.

If we assign final foo inside a method, the compiler knows that a method can be called multiple times, which means the value will have to be changed multiple times, which is not allowed for a final variable. So the compiler decides constructor is good choice! You can assign a value to a final variable only one time.

Scenario 2

private static final List foo = new ArrayList();

foo is now a static variable. When we create an instance of Test class, foo will not be copied to the object because foo is static. Now foo is not an independent property of each object. This is a property of Test class. But foo can be seen by multiple objects and if every object of Test which is created by using the new keyword which will ultimately invoke the Test constructor which changes the value of final static variable at the time of multiple object creation (Remember static foo is not copied in every object, but is shared between multiple objects.). To stop this, compiler knows final static cannot be initialized inside constructor and also cannot provide method to assign object to it. So we have to declare and define final List object at the same place at comment-1 in above program.

Scenario 3

t.foo.add("bar"); // Modification-2

Above Modification-2 is from your question. In the above case, you are not changing the first referenced object, but you are adding content inside foo which is allowed. Compiler complains if you try to assign a new ArrayList() to the foo reference variable.
Rule If you have initialized a final variable, then you cannot change it to refer to a different object. (In this case ArrayList)

final classes cannot be subclassed
final methods cannot be overridden. (This method is in superclass)
final methods can override. (Read this in grammatical way. This method is in a subclass)

Now let's see what is effectively final in java 1.8?

public class EffectivelyFinalDemo { //compile code with java 1.8
    public void process() {
        int thisValueIsFinalWithoutFinalKeyword = 10; //variable is effectively final
        
        //to work without final keyword you should not reassign value to above variable like given below 
        thisValueIsFinalWithoutFinalKeyword = getNewValue(); // delete this line when I tell you.
        
        class MethodLocalClass {
            public void innerMethod() {
                //below line is now showing compiler error like give below
                //Local variable thisValueIsFinalWithoutFinalKeyword defined in an enclosing scope must be final or effectively final
                System.out.println(thisValueIsFinalWithoutFinalKeyword); //on this line only final variables are allowed because this is method local class
                // if you want to test effectively final is working without final keyword then delete line which I told you to delete in above program.  
            }
        }
    }

    private int getNewValue() {
        return 0;
    }
}

Above program will throw error in java 1.7 or <1.8 if you do not use final keyword. Effectively final is a part of Method Local Inner classes. I know you would rarely use such effectively final in method local classes, but for interview we have to be prepared.

2 of 16
615

You are always allowed to initialize a final variable. The compiler makes sure that you can do it only once.

Note that calling methods on an object stored in a final variable has nothing to do with the semantics of final. In other words: final is only about the reference itself, and not about the contents of the referenced object.

Java has no concept of object immutability; this is achieved by carefully designing the object, and is a far-from-trivial endeavor.

🌐
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   1 week ago
Discussions

Why are final variables used in java?
Please ensure that: Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions You include any and all error messages in full You ask clear questions You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions. Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar If any of the above points is not met, your post can and will be removed without further warning. Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://imgur.com/a/fgoFFis ) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc. Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit. Code blocks look like this: public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above. If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures. To potential helpers Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns. More on reddit.com
🌐 r/javahelp
26
15
January 7, 2022
coding standards - Excessive use "final" keyword in Java - Software Engineering Stack Exchange
While I understand what the final keyword is used for in the context of classes and methods as well as the intent of its use for in regards to variables; however, the project I just started working... More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
August 4, 2011
java - Why would the 'final' keyword ever be useful? - Software Engineering Stack Exchange
It seems Java has had the power to declare classes not-derivable for ages, and now C++ has it too. However, in the light of the Open/Close principle in SOLID, why would that be useful? To me, the f... More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
May 12, 2016
Style poll: private static final LOG, log or logger?
I like the static final myself, but to each his or her own. ... I find it noisy to have this loggers in every class, especially if they then are never used in half of the classes. Also I don't see any advantage to use these static loggers. More replies More replies ... Presumably you could create your own Logger which passes the logging to a logger for the calling class. What do ya'll do with your logger object (java... More on reddit.com
🌐 r/java
23
4
February 11, 2015
🌐
W3Schools
w3schools.com › java › ref_keyword_final.asp
Java final Keyword
assert abstract boolean break byte case catch char class continue default do double else enum exports extends final finally float for if implements import instanceof int interface long module native new package private protected public return requires short static super switch synchronized this throw throws transient try var void volatile while Java String Methods

This is a favorite interview question. With this questions, the interviewer tries to find out how well you understand the behavior of objects with respect to constructors, methods, class variables (static variables) and instance variables.
Now a days interviewers are asking another favorite question what is effectively final from java 1.8.
I will explain in the end about this effectively final in java 1.8.

import java.util.ArrayList;
import java.util.List;

class Test {
    private final List foo; // comment-1    
    public Test() {
        foo = new ArrayList(); // comment-2
        foo.add("foo"); // Modification-1   comment-3
    }

    public void setFoo(List foo) {
       //this.foo = foo; Results in compile time error.
    }
}

In the above case, we have defined a constructor for 'Test' and gave it a 'setFoo' method.

About constructor: Constructor can be invoked only one time per object creation by using the new keyword. You cannot invoke constructor multiple times, because constructor are not designed to do so.

About method: A method can be invoked as many times as you want (Even never) and the compiler knows it.

Scenario 1

private final List foo;  // 1

foo is an instance variable. When we create Test class object then the instance variable foo, will be copied inside the object of Test class. If we assign final foo inside the constructor, then the compiler knows that the constructor will be invoked only once, so there is no problem assigning it inside the constructor.

If we assign final foo inside a method, the compiler knows that a method can be called multiple times, which means the value will have to be changed multiple times, which is not allowed for a final variable. So the compiler decides constructor is good choice! You can assign a value to a final variable only one time.

Scenario 2

private static final List foo = new ArrayList();

foo is now a static variable. When we create an instance of Test class, foo will not be copied to the object because foo is static. Now foo is not an independent property of each object. This is a property of Test class. But foo can be seen by multiple objects and if every object of Test which is created by using the new keyword which will ultimately invoke the Test constructor which changes the value of final static variable at the time of multiple object creation (Remember static foo is not copied in every object, but is shared between multiple objects.). To stop this, compiler knows final static cannot be initialized inside constructor and also cannot provide method to assign object to it. So we have to declare and define final List object at the same place at comment-1 in above program.

Scenario 3

t.foo.add("bar"); // Modification-2

Above Modification-2 is from your question. In the above case, you are not changing the first referenced object, but you are adding content inside foo which is allowed. Compiler complains if you try to assign a new ArrayList() to the foo reference variable.
Rule If you have initialized a final variable, then you cannot change it to refer to a different object. (In this case ArrayList)

final classes cannot be subclassed
final methods cannot be overridden. (This method is in superclass)
final methods can override. (Read this in grammatical way. This method is in a subclass)

Now let's see what is effectively final in java 1.8?

public class EffectivelyFinalDemo { //compile code with java 1.8
    public void process() {
        int thisValueIsFinalWithoutFinalKeyword = 10; //variable is effectively final
        
        //to work without final keyword you should not reassign value to above variable like given below 
        thisValueIsFinalWithoutFinalKeyword = getNewValue(); // delete this line when I tell you.
        
        class MethodLocalClass {
            public void innerMethod() {
                //below line is now showing compiler error like give below
                //Local variable thisValueIsFinalWithoutFinalKeyword defined in an enclosing scope must be final or effectively final
                System.out.println(thisValueIsFinalWithoutFinalKeyword); //on this line only final variables are allowed because this is method local class
                // if you want to test effectively final is working without final keyword then delete line which I told you to delete in above program.  
            }
        }
    }

    private int getNewValue() {
        return 0;
    }
}

Above program will throw error in java 1.7 or <1.8 if you do not use final keyword. Effectively final is a part of Method Local Inner classes. I know you would rarely use such effectively final in method local classes, but for interview we have to be prepared.

Answer from AmitG on Stack Overflow
🌐
Baeldung
baeldung.com › home › java › core java › the “final” keyword in java
The "final" Keyword in Java | Baeldung
June 14, 2025 - Methods marked as final cannot be overridden. When we design a class and feel that a method shouldn’t be overridden, we can make this method final. We can also find many final methods in Java core libraries.
🌐
Wikipedia
en.wikipedia.org › wiki › Final_(Java)
final (Java) - Wikipedia
October 29, 2025 - In the Java programming language, the final keyword is used in several contexts to define an entity that can only be assigned once. Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may ...
Find elsewhere
🌐
DataCamp
datacamp.com › doc › java › final
final Keyword in Java: Usage & Examples
Java keywordsIntroduction To JavaJava File HandlingJava Language BasicsJava ArraysJava Object-Oriented Programming ... 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 ...
Top answer
1 of 4
151

There are many references suggesting a liberal use of final. The Java Language Specification even has a section on final variables. Various rules in static analysis tools also support this - PMD even has a number of rules to detect when final can be used. The pages that I linked to provide a number of points as to what final does and why you should use it liberally.

For me, the liberal use of final accomplished two things in most code, and these are probably the things that drove the author of your code sample to use it:

  1. It makes the intent of the code much more clear, and leads to self-documenting code. Using final prevents the value of a primitive object from changing or a new object being made and overwriting an existing object. If there's no need to change the value of a variable and someone does, the IDE and/or compiler will provide a warning. The developer must either fix the problem or explicitly remove the final modifier from the variable. Either way, thought is necessary to ensure the intended outcome is achieved.

  2. Depending on your code, it serves as a hint for the compiler to potenitally enable optimizations. This has nothing to do with compile time, but what the compiler can do during compilation. It's also not guaranteed to do anything. However, signaling the compiler that the value of this variable or the object referred to by this variable will never change could potentially allow for performance optimizations.

There are other advantages as well, related to concurrency. When applied at a class or method level, having to do with ensuring what can be overridden or inherited. However, these are beyond the scope of your code sample. Again, the articles I linked to go far more in-depth into how you can apply final.

The only way to be sure why the author of the code decided to use final is to find the author and ask for yourself.

2 of 4
50

The principle benefits of "final" in my mind are two-fold:

  • Final variables are "safer" than non-final variables, because once they are bound there is never a question about what their current state is.
  • Because of the above, making a variable final relieves the programmer of excess mental juggling - he/she doesn't have to scan through the code to see if the variable has changed. This happy state-of-affairs will be familiar to anyone who has spent any time in a functional-language setting.

As for this specific example, it may be that the programmer picked up the "final" habit and just applies the "final" keyword everywhere as a matter of course. (I am skeptical of the notion that the final keyword would help the compiler when talking about individual assignments — surely it doesn't need the help to determine only one assignment took place?)

I'm of the opinion that Java got it backwards — there should be no "final" keyword for variables, everything should be "final" by default, and if you want a mutable variable you should have to add a keyword for that ("var" or some such). (As another commenter mentioned, scala has two keywords — "val" and "var" for final and non-final variables, respectively - I'll take it).

🌐
Quora
quora.com › What-happens-when-you-declare-a-variable-as-final-in-Java
What happens when you declare a variable as final in Java? - Quora
Answer (1 of 2): A “variable” (field) declare as [code ]final[/code] in Java means the field is a constant. As such, once the value is set, it cannot be changed for the life of the application.
🌐
Quora
quora.com › In-Java-what-does-final-do
In Java, what does 'final' do? - Quora
Answer (1 of 18): Final Keyword in Java The final keyword in java is used to restrict the user. The java final keyword can be used in many context. Final can be: 1) final variable 2) final method 3) final class 1) final variable final variables ...
🌐
CodeGym
codegym.cc › java blog › keywords in java › java final keyword
Final Keyword In Java
January 14, 2025 - For variables of a primitive type, the final keyword means that the value, once assigned, cannot be changed. For reference variables, it means that after an object is assigned, you cannot change the reference to that object.
🌐
Quora
quora.com › Should-I-almost-always-use-final-variables-in-Java
Should I almost always use final variables in Java? - Quora
Answer (1 of 4): That’s debatable. First lets get one thing out of the way: optimization. In principle Java could optimize the use of final variables, but - as far as I know - no such optimization takes place today. So you don’t need [code ]final[/code] for that.
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-the-purpose-of-a-final-variable-in-Java
What is the purpose of a final variable in Java? - Quora
Answer (1 of 13): When the variable is declare as final, initialize the value to it, then you cannot change the value of that particular variable. Final variables can be initialized its value only inside the constructors. [code]public class final_variable_in_default_constructor { final_variabl...
🌐
Medium
medium.com › @alexthedev › final-keyword-in-java-dd0281080643
final Keyword in Java. why, when and how to use it | by Alexandru Nastase | Medium
September 26, 2022 - The final keyword in Java can be used for different purposes. Most commonly, it is used to create immutable objects. This means that once an object is created, it cannot be modified.
🌐
Quora
quora.com › What-is-a-final-keyword-in-Java-and-what-is-the-use-of-interfaces-in-real-time
What is a final keyword in Java, and what is the use of interfaces in real time? - Quora
Answer (1 of 2): Final keyword used in 3 types , 1. Use Final as variables declaration. final int a=10: Here the value of the variables will not change as it was declared with final.
🌐
CodeJava
codejava.net › java-core › the-java-language › final-keyword
Java final keyword example
August 19, 2019 - He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube. ... Sorry. I misunderstodd :( Quoting Nam: It is overload, not override. Quoting Gopalakrishnan: final class can be override by same class.
🌐
Baeldung
baeldung.com › home › java › core java › the java final keyword – impact on performance
The Java final Keyword – Impact on Performance | Baeldung
March 26, 2025 - The main purpose of effectively final variables is to enable lambdas to use local variables that are not explicitly declared final. However, the Java compiler won’t perform static code optimization for effectively final variables the way it does for final variables.
🌐
IONOS
ionos.com › digital guide › websites › web development › java final
How to use Java final for classes, methods and variables
January 3, 2025 - The keyword final is used in Java to create elements that cannot be changed. You can apply this modifier to classes, methods and variables.