Ключевое слово Java final

Ключевое слово final означает завершенный и может быть использовано для объявления переменных, методов и классов.

1. final переменные

Переменная может быть объявлено как final, что позволяет предотвратить изменение содержимого переменной, сделав ее, по существу, константой.

final переменная класса, объявленная как не static, должна инициализироваться при объявлении или в теле конструктора или блоке инициализации, иначе произойдет ошибка компиляции.

Кроме переменных, объявленными как final могут быть параметры метода и локальные переменные. final переменные, объявленные как static, должны быть проинициализированы при объявлении или в блоке инициализации, также объявленном как static. В противном случае, опять получится ошибка компиляции. 

Следующий пример показывает различные варианты объявления завершенных переменных:

public class FinalVariables {
    public static final int FILE_NEW = 1;
    private final String someString = "something";

    public static void print(final double d) {
        //  FILE_NEW = 2;
        final String str;
        str = "someString";
        //  str = "";
        //  d = 4;
        System.out.println("FILE_NEW = " + FILE_NEW);
        System.out.println("str = " + str);
        System.out.println("d = " + d);
    }

    public static void main(String[] args) {
        print(3);
    }
}

Ключевое слово final означает завершенный и может быть использован для объявления переменных, методов и классов.

2. Константы Java

Константы – это переменные, значение которых не меняется. Константами в Java принято называть public static final переменные класса. Имена констант следует задавать только заглавными буквами, а слова в имени разделять знаком подчеркивания: MAX_WEIGHT.

Константы часто используются для борьбы c магическими (или волшебными) числами, то есть непонятно что означающими числами или строками. Например, следующий код содержит несколько раз повторяющееся магическое число 9.81:

public class PhysicsMagicNumber {
    public static double potentialEnergy(double mass, double height) {
        return mass * height * 9.81;
    }

    public static double getVelocity(double time) {
        return time * 9.81;
    }

    public static double getDistance(double time) {
        return 9.81 * time * time / 2;
    }
}

Давайте перепишем код введя константу с именем ACCELERATION. Какие преимущества дает нам введение константы? Во-первых имя константы уже объясняет значение этого числа, и во-вторых при желании изменить значение ACCELERATION, это можно сделать в одном месте. После рефакторинга:

public class Physics {
    public static final double ACCELERATION = 9.81;

    public static double potentialEnergy(double mass, double height) {
        return mass * height * ACCELERATION;
    }

    public static double getVelocity(double time) {
        return time * ACCELERATION;
    }

    public static double getDistance(double time) {
        return ACCELERATION * time * time / 2;
    }
}

3. final методы

Чтобы запретить переопределение метода в классах наследниках, в начале его объявления следует указать ключевое слово final. Такие методы еще называют завершенными.

Не имеет смысла объявлять метод private final так как private метод не виден в наследниках, соответственно не может быть переопределен.

Также конструктор не может быть объявлен как final.

Класс O содержит завершенный метод, который не может быть переопределен в классе наследнике P. При попытке возникнет ошибка компиляции:

public class O {
    final void method() {
        System.out.println("Это завершенный метод");
    }
}
public class P extends O {
    //Этот метод не может быть переопределен
    /* void method() {
        System.out.println("Недопустимо");
    }*/
}

4. final классы

Для предотвращения наследование класса в начале объявления класса следует указать ключевое слово final. Объявление класса завершенным неявно делает завершенными и все его методы. Одновременное объявление класса как abstract и final недопустимо.

final class А{
	//…
}
class B extends A {// ОШИБКА! Класс А не может иметь подклассы
	//…
}
Read also:
Comments