Week 13 — What is the purpose of the final keyword?

Question of the Week #13
What is the purpose of the final keyword?
24 Replies
Eric McIntyre
Eric McIntyre2y ago
The final keyword is used to declare that a variable cannot be changed later in the program. For example:
final int doge = 1
final int doge = 1
means that the int doge cannot be changed later in the program (aka the variable is a constant).
Submission from Dogepressed#1205
Eric McIntyre
Eric McIntyre2y ago
The final keyword has 3 types it can be used on. Data, Methods, and Classes. We'll review the different use cases and the impact. Data
private final Object myObject;
private final int myInt;
public static final int MY_CONSTANT = 0;
private final Object myObject;
private final int myInt;
public static final int MY_CONSTANT = 0;
For Data it breaks into three different use cases. - Limiting the scope of Object Assignment. The field private final Object myObject can only be assigned once in the scope of the constructor. If you try to reassign the reference to a new object outside of the constructor, you'll get a build error, or if you try multiple assignments in the Constructor scope you'll also get a build error. Note that private final Object only creates an immutable reference to the object, if all the inner fields aren't final you can still get a mutable object. This usage of final is nice for enforcing a more functional design, since you can create Objects with immutable states. - Creating local constants. Where private final Object myObject creates an immutable reference, private final <Primitive> myPrimitive creates locally scoped constants. This can be combined with private final Object myObject to create completely immutable data. - Creating global constants. public static final <Object/Primitive> myThing = <Value> creates a globally scoped reference. This concept has been used for something like a global String bank, (Not to be confused with Java's Actual String bank), referencing Math Constants, Referencing Default Configuration, etc. The nice this is that in combination with final, we can use static with less fear about any concurrency issues. Methods/Classes
public final void myAction() {
// doing something
}
public final void myAction() {
// doing something
}
final in this context means the method/class cannot be Overriden. Given how Java leads itself to OOP, this can be a useful method to make sure that certain aspects of a contract are upheld. For example you might have a business logic class with the following. ```java public class MyActionService
Eric McIntyre
Eric McIntyre2y ago
extends AbstractActionService { public MyActionService() { this.myActionName = "Custom Action"; } public abstract class AbstractActionService { private final String myActionName; public void doAction(); public final void logAction() { log.info(myActionName + " was taken at " + Instance.now()); } } } ``` Now we can have a class extend our class, but not override our logAction, which can have a strict contract for the format. For classes this keyword means that the class can't be extended. This feature is useful for when library developers want to prevent extension of their classes.
⭐ Submission from LeanusCrain#5877
Eric McIntyre
Eric McIntyre2y ago
A final keyword declares the method can not be overridden in any sub class where the method is referenced
Eric McIntyre
Eric McIntyre2y ago
final int age = 12
Submission from Prinzessin#0001
Eric McIntyre
Eric McIntyre2y ago
final = once the variable is assigned, it cannot be assigned again
Submission from toastmush#5955
Eric McIntyre
Eric McIntyre2y ago
The final keyword does not allow whatever is being created to have its value changed Example 1: A final variable:
class Driver {
public static void main(String[] args){
final String example = "The example variable can't have another value after me";
System.out.println(example);
}
}
class Driver {
public static void main(String[] args){
final String example = "The example variable can't have another value after me";
System.out.println(example);
}
}
Example 2: A final method:
class Driver {
public final String doIt(){
System.out.println("No matter what classes may inherit this class, this method cannot be overridden");
return "haha";
}
}
class Driver {
public final String doIt(){
System.out.println("No matter what classes may inherit this class, this method cannot be overridden");
return "haha";
}
}
Eric McIntyre
Eric McIntyre2y ago
Example 3: A final class:
final class Driver {
public void doIt(){
System.out.print("No class can override this class because it's final");
}
}
final class Driver {
public void doIt(){
System.out.print("No class can override this class because it's final");
}
}
Submission from amicharski#7113
Eric McIntyre
Eric McIntyre2y ago
The final keyword is used when you declare a variable. It is used to make the variable value unchangeable. For all primitive types, the value will never be changed. For objects such as Lists, Arrays, Maps, and similar objects, you will not be able to create a new object, but you will still be able to modify the contents of that object.
final int myNum = 3;
// `myNum` will always be 3

final ArrayList<Integer> numbers = new ArrayList<>();
// `numbers` cannot be assigned a new arraylist now that it has already been declared and assined, however we can still modify the contents of that arraylist

numbers.add(3);
final int myNum = 3;
// `myNum` will always be 3

final ArrayList<Integer> numbers = new ArrayList<>();
// `numbers` cannot be assigned a new arraylist now that it has already been declared and assined, however we can still modify the contents of that arraylist

numbers.add(3);
Submission from MinecraftMan1013#7242
Eric McIntyre
Eric McIntyre2y ago
the keyword 'final' is used to declare a variable, method or class that cannot be modified or extended.
Submission from pwrpl3#8029
Eric McIntyre
Eric McIntyre2y ago
The final keyword makes a variable read only. When a field has the final modifier, only the constructor or static constructor can set it, once. No more modifications are allowed. The same happens with a local with the final modifier, it can only be set once.
class Foo {
final static String staticValue;
static {
staticValue = "abc"; // legal, <clinit>
}
final String value;
Foo(String value) {
this.value = value; // legal
}

public void print() {
System.out.println(this.value);
this.value = "abc"; // illegal, field has final modifier and we're not in <init>
}
}

void main() {
final String s;
s = "abc"; // legal, only assignment
s = "ddd"; // illegal, already assigned
}
class Foo {
final static String staticValue;
static {
staticValue = "abc"; // legal, <clinit>
}
final String value;
Foo(String value) {
this.value = value; // legal
}

public void print() {
System.out.println(this.value);
this.value = "abc"; // illegal, field has final modifier and we're not in <init>
}
}

void main() {
final String s;
s = "abc"; // legal, only assignment
s = "ddd"; // illegal, already assigned
}
Submission from 0x150#9699
Eric McIntyre
Eric McIntyre2y ago
When marking a variable with final, it cannot be reassigned.
int i=0;
i++;//allowed
i=123;//allowed
final int j=0;
//i++;//compilation error
//i=123;//compilation error
int k=j;//k is a copy of j and k can be changed
k++;//allowed
int i=0;
i++;//allowed
i=123;//allowed
final int j=0;
//i++;//compilation error
//i=123;//compilation error
int k=j;//k is a copy of j and k can be changed
k++;//allowed
For reference variables (objects), it is possible to change the content of the referenced objects but it is not possible to reassign the variable
public class SomeClass{
public int i=0;//just public for demonstration
public void setI(int i){
this.i=i;
}
}
public class SomeClass{
public int i=0;//just public for demonstration
public void setI(int i){
this.i=i;
}
}
final SomeClass o=new SomeClass();
o.i=123;
o.setI(456);
//o=new SomeClass();//compilation error because final variables cannot be reassigned
final SomeClass o=new SomeClass();
o.i=123;
o.setI(456);
//o=new SomeClass();//compilation error because final variables cannot be reassigned
This behaviour is the similar with fields. final fields need to be initialized in the declaration, initializer blocks or in the constructor.
class SomeClass{
private final int i=123;
private final String s;
//private final int unitializedVariable;//compilation error because variable is not initialized
public SomeClass(){
this.s="Hello World";
//this.s="Something else";//compilation error
//this.i=456;//compilation error
}
public void someMethod(){
System.out.println(s);//Hello World
System.out.println(i);//123
//i=456;//compilation error
//s="whatever";//compilation error
}
}
class SomeClass{
private final int i=123;
private final String s;
//private final int unitializedVariable;//compilation error because variable is not initialized
public SomeClass(){
this.s="Hello World";
//this.s="Something else";//compilation error
//this.i=456;//compilation error
}
public void someMethod(){
System.out.println(s);//Hello World
System.out.println(i);//123
//i=456;//compilation error
//s="whatever";//compilation error
}
}
Eric McIntyre
Eric McIntyre2y ago
The final keyword can also be used on classes. If a class is marked with final, it is not possible to create subclasses of the said class:
final class FinalClass{}
class NonFinalClass{}
public class AllowedSubclass extends NonFinalClass{}
//public class IllegalClass extends FinalClass{}//compilation error
final class FinalClass{}
class NonFinalClass{}
public class AllowedSubclass extends NonFinalClass{}
//public class IllegalClass extends FinalClass{}//compilation error
A class is called "immutable", if all its fields are marked with final and the class itself is final. If a class is immutable, its fields can never change their associated values.
final class ImmutableClass{
private final String s;
private final int i;
public ImmutableClass(String s, int i){
this.s=s;
this.i=i;
}
//possibly other methods
}
class ExtendableClassWithFinalFieldsOnly{//this class is not immutable because it is not final
private final String s;
private final int i;
public ExtendableClassWithFinalFieldsOnly(String s, int i){
this.s=s;
this.i=i;
}
//possibly other methods
}
final class ClassWithNonFinalFields{
private String s;//this field is not final hence the class is not immutable
private final int i;
public ClassWithNonFinalFields(String s, int i){
this.s=s;
this.i=i;
}
//possibly other methods
}
final class ImmutableClass{
private final String s;
private final int i;
public ImmutableClass(String s, int i){
this.s=s;
this.i=i;
}
//possibly other methods
}
class ExtendableClassWithFinalFieldsOnly{//this class is not immutable because it is not final
private final String s;
private final int i;
public ExtendableClassWithFinalFieldsOnly(String s, int i){
this.s=s;
this.i=i;
}
//possibly other methods
}
final class ClassWithNonFinalFields{
private String s;//this field is not final hence the class is not immutable
private final int i;
public ClassWithNonFinalFields(String s, int i){
this.s=s;
this.i=i;
}
//possibly other methods
}
Records are implicitly immutable.
record SomeRecord(String s, int i){}
record SomeRecord(String s, int i){}
⭐ Submission from dan1st#7327
Eric McIntyre
Eric McIntyre2y ago
The final keyword is used to make variables or whatever only able to be assigned once, when its assigned it cannot be reassigned.
private final String line = "Hello, World";
private final String line = "Hello, World";
trying to reassign a final variable results in an exception being thrown to your doorstep.
private final String line = "";

void fun() {
line = "Hello, World";
}
private final String line = "";

void fun() {
line = "Hello, World";
}
final variables need to be initialized at either the same line its being created in a constructor from the same class the variable is in or in a "instance initializer block". Constructor example:
public Main() {
this.line = "Hello, World!";
}
public Main() {
this.line = "Hello, World!";
}
Instance Initializer example:
{
this.line = "Hello, World";
}
{
this.line = "Hello, World";
}
Submission from Aussied#7593
Eric McIntyre
Eric McIntyre2y ago
to make sure that a variable can not be edited for example:
final int a = 10
int a = 9
final int a = 10
int a = 9
would be invalid
Submission from AmyDon#1791
Eric McIntyre
Eric McIntyre2y ago
The purpose of the final keyword is, to mark a variable as a constant variable, which should not be changed later in the code. Here an example:
public class MyProgram{
private String quote;
private String author;

public MyProgram(String quote){
this.quote = quote;
this.author = "MyName";
}

public void addAuthorToString(){
this.quote += "\n~" + this.author;
}
public class MyProgram{
private String quote;
private String author;

public MyProgram(String quote){
this.quote = quote;
this.author = "MyName";
}

public void addAuthorToString(){
this.quote += "\n~" + this.author;
}
Here you have a class and a function where you add the Author to a quote. You want the Author to always be yourself in this example, so you added the name in the constructor. Instead of creating a variable and setting the name of the author, you could simply change the variable to be a final string like this:
public class MyProgram{
private String quote;
private final String author = "MyName";

public MyProgram(String quote){
this.quote = quote;
this.author = "AnotherName"; //This will throw an error saying that the final variable cannot be changed
}

public void addAuthorToString(){
this.quote += "\n~" + this.author;
}
public class MyProgram{
private String quote;
private final String author = "MyName";

public MyProgram(String quote){
this.quote = quote;
this.author = "AnotherName"; //This will throw an error saying that the final variable cannot be changed
}

public void addAuthorToString(){
this.quote += "\n~" + this.author;
}
Therefore, use a final variable, if you want to use the same value the whole time instead of creating a normal attribute and setting it once, to not accidentally change the value.
Submission from Giotsche#5027
Eric McIntyre
Eric McIntyre2y ago
In Java, the final keyword can be used in several contexts to indicate that a variable, method, or class cannot be changed after it has been initialized or defined. 1. Variable: When a variable is declared as final, its value cannot be changed once it is assigned. 2. Method: When a method is declared as final, it cannot be overridden by any subclass. 3. Class: When a class is declared as final, it cannot be extended by any subclass. The purpose of using final keyword is to ensure that the value or behavior of a variable, method, or class remains constant throughout the program, which can prevent bugs and make the code more readable and maintainable. It also provides a way to enforce immutability, which can help in multithreaded environments.
Eric McIntyre
Eric McIntyre2y ago
Here are some examples of using the final keyword in Java: 1. Variable:
final int MAX_VALUE = 100;
// MAX_VALUE cannot be changed later in the code
final int MAX_VALUE = 100;
// MAX_VALUE cannot be changed later in the code
2. Method:
public class Parent {
public final void printMessage() {
System.out.println("Hello from Parent class");
}
}

public class Child extends Parent {
// This will cause a compile-time error
public void printMessage() {
System.out.println("Hello from Child class");
}
}
public class Parent {
public final void printMessage() {
System.out.println("Hello from Parent class");
}
}

public class Child extends Parent {
// This will cause a compile-time error
public void printMessage() {
System.out.println("Hello from Child class");
}
}
3. Class:
public final class MyClass {
// This class cannot be extended by any subclass
}
public final class MyClass {
// This class cannot be extended by any subclass
}
⭐ Submission from LynnCodes#2568
Eric McIntyre
Eric McIntyre2y ago
The final keyword basically means that the thing is final, depending on the context. One of the most known usage of the keyword is in variables. If the keyword is present after the variable visibility it means that this variable's value is constant and will remain like this, even reflections won't be able to modify it. On classes, final variable must be initialized, the code will not compile if your class will initialize without the variable with it. The following is an example for classes:
public class DiscordServer {
public final String name;

public DiscordServer(String name) {
this.name = name;
}
}
public class DiscordServer {
public final String name;

public DiscordServer(String name) {
this.name = name;
}
}
The keyword can also be used on classes themselves, and on methods. On Classes it means that the class is not extendable, and on methods it means that it is not overridable. This is how final is used on them:
public final class DiscordServer {

public final void delete() {
//code here, cannot be changed by overriding
}
}
public final class DiscordServer {

public final void delete() {
//code here, cannot be changed by overriding
}
}
Note There is no point of using a final method inside a final class, as you cannot extend the class anyway, which is required to override it's methods, this was just an example.
⭐ Submission from BlueTree242#9734
Eric McIntyre
Eric McIntyre2y ago
Final keyword is a keyword which can be used to make a variable constant, meaning you can assign its value at the time of initialization but you cannot assign any value to it after initialization, example: Non-final variable
int i = 0;
System.out.println(i); // Outputs 0
i = 10;
System.out.println(i); // Outputs 10
int i = 0;
System.out.println(i); // Outputs 0
i = 10;
System.out.println(i); // Outputs 10
Final variable
final int = 0;
System.out.println(i); // Outputs 0
i = 10; // Gives error
final int = 0;
System.out.println(i); // Outputs 0
i = 10; // Gives error
Submission from Rudiemc#4088
Eric McIntyre
Eric McIntyre2y ago
The final keyword in Java indicates that the variable cannot be changed. These variables cannot be inherited either.
public final int e = 2.71828;
public final int e = 2.71828;
Submission from Maruvert#2038
Eric McIntyre
Eric McIntyre2y ago
The final keyword is a non-access modifier used for classes, methods and variabes alike that prevent them from being changed lateron in our code.
Submission from mayokun#5069
Eric McIntyre
Eric McIntyre2y ago
In Java, the final keyword is a non-access modifier. It can be used with variables, methods, and classes. Once any variable, method or class is declared final, it can be assigned only once. So the final variable can't be reinitialized with another value.
Submission from protozoid#5861
Eric McIntyre
Eric McIntyre2y ago
The final keyword ensures that values, methods, or classes remain unchanged after initialization, providing a level of safety and predictability in the program. So here's an example:
final double PI = 3.14159; //declaring a constant value of PI
final double PI = 3.14159; //declaring a constant value of PI
Here, the variable PI is declared as final, which means that its value cannot be changed after initialization.
Submission from DTechish#5832
Want results from more Discord servers?
Add your server