Static и final
Обычно поле или метод принадлежит конкретному объекту. Но иногда значение должно быть общим для всего класса,
а иногда — наоборот, его нужно запретить заменять после инициализации.
Для этих двух задач в Java используются ключевые слова static и final.
static — один член на весь класс
Член с модификатором static принадлежит классу, а не отдельному объекту.
Поэтому все экземпляры работают с одним и тем же статическим полем.
class User {
static int count;
String name;
User(String name) {
this.name = name;
count++;
}
}
User first = new User("Alice");
User second = new User("Bob");
System.out.println(User.count); // 2
У first и second разные поля name,
но поле count общее. Обращаться к статическим членам принято через имя класса:
User.count.
Статическими могут быть и методы. Такой метод можно вызвать без создания объекта, если для его работы не нужно состояние конкретного экземпляра.
class MathUtils {
static int square(int value) {
return value * value;
}
}
int result = MathUtils.square(5);
Статический метод не связан с конкретным объектом, поэтому внутри него нельзя напрямую использовать
нестатические поля и методы или ключевое слово this.
Для доступа к состоянию экземпляра сначала нужен сам экземпляр.
final — назначить один раз
Для переменной final означает, что после присваивания ей нельзя назначить другое значение.
final int maxAttempts = 3;
// maxAttempts = 4; // compile-time error
То же правило работает для полей. final-поле можно инициализировать сразу
или присвоить ему значение в конструкторе. После этого заменить значение уже нельзя.
class Order {
final int id;
Order(int id) {
this.id = id;
}
}
final User user = new User("Alice");
user.name = "Bob"; // OK
// user = new User("Carol"); // compile-time error
final у методов и классов
Модификатор final можно применять не только к переменным.
final-метод нельзя переопределить в подклассе,
а от final-класса нельзя наследоваться.
class BaseService {
final void printVersion() {
System.out.println("1.0");
}
}
final class AppConfig {
}
Это используют, когда поведение метода или сам класс не должны изменяться через наследование.
Сам по себе final не делает остальные поля объекта неизменяемыми.
static final — константы класса
Если значение должно быть одновременно общим для класса и назначаться только один раз,
модификаторы объединяют: static final.
Так обычно объявляют константы класса.
class Limits {
static final int MAX_ATTEMPTS = 3;
}
System.out.println(Limits.MAX_ATTEMPTS);
Для таких констант в Java принято использовать имена в верхнем регистре с подчёркиваниями.
Важно различать роли модификаторов: static делает член общим для класса,
а final запрещает присвоить ему новое значение после инициализации.