Chapter 5 - Java for Beginners Course

Final Classes and Class Members

In the same way that Java allows us to define inheritance relationships between classes, Java also provides us with a mechanism to prevent a class from being extended, to prevent a method from being overridden, or for a variable value from changing, by using the final keyword.

The effect of the final keyword depends on the context where it is being used, as follows:

final classes

We can use final in the class declaration to indicate that we don’t want to allow a class to have subclasses.

For example, let’s assume we’re building a library that holds the data of a dictionary and we want to model each entry we have, and we define a DictionaryEntry class for this.

Let’s also assume we don’t want users of our library to subclass it:

public final class DictionaryEntry {
    private String word;

    private String definition;

    public DictionaryEntry(String word, String definition) {
        this.word = word;
        this.definition = definition;
    }

    public void printEntry() {
        System.out.println(word + ": " + definition);
    }
}
To clarify, a final class can still extend from another class, but no class can extend from it.

final methods

In a similar way, if we want to allow our class to be extended but want to avoid certain methods from being overridden, you can mark those methods as final.

For example, maybe all we’re concerned about is that the behaviour of our printEntry method isn’t changed:

public class DictionaryEntry {
    private String word;

    private String definition;

    public DictionaryEntry(String word, String definition) {
        this.word = word;
        this.definition = definition;
    }

    public final void printEntry() {
        System.out.println(word + ": " + definition);
    }
}

In this case, users of our library can extend our DictionaryEntry class, but we are providing certain restrictions about the methods they can override.

final fields

A different behavior of the final keyword is when it is used with fields or variables in general. In this case, the final keyword indicates that the value of the variable can only be set once. If we try to change the value of a final variable, the compiler will show an error indicating that a value for that variable may have already been assigned.

In our DictionaryEntry class, it might not make sense to allow the word or definition to change after the object has been created, so we can mark those 2 fields as final:

private final String word;

private final String definition;
What happens if you don’t assign a value to word or definition in the constructor? Do you get a compilation error?
final classes and fields are a starting point to Immutable Objects which we won’t cover in this course.

Static final fields

A common pattern in Java is to declare constant values in an application as static final variables. These constants, by convention, are named in upper case.

For example:

public class DictionaryEntry {
    private static final String WORD_SEPARATOR = ": ";

    private final String word;

    private final String definition;

    public DictionaryEntry(String word, String definition) {
        this.word = word;
        this.definition = definition;
    }

    public final void printEntry() {
        System.out.println(word + WORD_SEPARATOR + definition);
    }
}
Code in GitHub

Get the code for this tutorial using the links below.

Project Repo
Download code for this step
Main class for this step
Dependencies

This is a list of recommended tutorials or courses that might be useful before starting this one.

Contents
Welcome to the Course!
Course Introduction
Chapter 1 - Building Blocks
Quick introduction to Java Variables Classes And Objects Class Example - Defining a class Object Examples - Creating instances Java Application Example - Running our first app Accessing class members - The dot operator Packages - Organizing the code
Chapter 2 - Primitives and Operators
Primitives Arithmetic Operators Assignment Operator Unary Operators Equality and Relational Operators Conditional Operators
Chapter 3 - Statements and Control Flow
Expressions Statements If-Then Statement If-Then-Else Statement More If Statements Switch Statement While and Do-While Statements For Statement Branching Statements Exception Handling
Chapter 4 - Code Example
Example Project - A Simple Vending Machine Adding money Delivering Items Giving Change
Chapter 5 - Classes and Interfaces
Introduction Access Level Modifiers Class Declaration - Class, Methods and Fields Class Declaration - Constructors Inheritance Basics Inheritance - Constructors Inheritance - Methods and Fields Polymorphism Abstract Classes and Methods Interfaces Static Class Members Class Composition Final Classes and Class Members Generic Classes
Chapter 6 - Base Object Behaviors
Introduction Type Comparison Type Casting Object Equality - The Contract Object Equality - Common Pitfalls Object String Representation Garbage Collection Object Comparison Primitive Wrappers and Autoboxing
Chapter 7 - Data Structures
Introduction Arrays - Declaration and Creation Arrays - Basic Operations Core Collection Interfaces List and ArrayList - Basic Operations ArrayList Internals Introduction to Hash Tables Map and HashMap - Basic Operations Set and HashSet - Basic Operations
Chapter 8 - Anonymous classes and lambdas
Introduction Filtering a List Anonymous Classes Lambdas Built-in Functional Interfaces
Chapter 9 - Streams
Introduction Creating Streams Intermediate Operations Terminal Operations