Что такое static
static значит «принадлежит классу, а не отдельному объекту». Обычное поле у каждого объекта своё, статическое — одно на всех. Обычный метод вызывают через объект (a.introduce()), статический — через имя класса (Math.max(3, 7)), объект для этого не нужен.
Поле: одно на всех
public class Main {
public static void main(String[] args) {
Counter a = new Counter();
Counter b = new Counter();
Counter c = new Counter();
System.out.println(Counter.count);
System.out.println(a.id + " " + b.id + " " + c.id);
}
}
class Counter {
static int count = 0;
int id;
Counter() {
count++;
id = count;
}
}3
1 2 3count — статическое поле: оно одно, и каждый конструктор увеличивает одно и то же значение. id — обычное поле: у каждого объекта своё. Статическое поле читают через имя класса — Counter.count.
Метод: без объекта
Статический метод не привязан к объекту, поэтому внутри него нет this и нельзя напрямую обратиться к обычным полям и методам. Так устроены вспомогательные методы, которым нужны только параметры: Math.sqrt(x), Integer.parseInt(s), Arrays.sort(a).
Метод main статический, потому что программа начинается, когда никаких объектов ещё нет: Java вызывает Main.main(...), ничего не создавая.
Ошибка non-static … cannot be referenced from a static context
public class Main {
void greet() {
System.out.println("Привет!");
}
public static void main(String[] args) {
greet();
}
}Компилятор остановится:
Main.java:7: error: non-static method greet() cannot be referenced from a static contextmain — статический, а greet — обычный метод, ему нужен объект. Как исправить, зависит от того, нужны ли методу поля объекта.
Поля объекта не нужнысделайте метод статическим
Так обычно и пишут в учебных программах:
public class Main {
static void greet() {
System.out.println("Привет!");
}
public static void main(String[] args) {
greet();
}
}Привет!Метод работает с полямисоздайте объект
Создайте объект и вызовите метод через него:
public class Main {
void greet() {
System.out.println("Привет!");
}
public static void main(String[] args) {
Main app = new Main();
app.greet();
}
}Привет!То же с полями: non-static variable count cannot be referenced from a static context — либо поле static, либо обращение через объект.
Константы: static final
Значение, которое одно на всю программу и не меняется, объявляют static final и называют большими буквами:
static final int MAX_STUDENTS = 30;Такие константы есть и в стандартной библиотеке: Math.PI, Integer.MAX_VALUE.
Подводные камни
- Не делайте всё статическим «чтобы работало». Статическое поле общее для всех объектов: если хранить в нём имя студента, у всех студентов окажется одно имя — последнее присвоенное.
- Статический метод не переопределяется в наследнике так, как обычный: полиморфизм работает только с обычными методами.
- Статический метод можно вызвать и через объект (
a.staticMethod()), но так путают читателя — пишите имя класса.