В некоторых случаях следует, чтобы некоторые члены принадлежали только классу и не были частью объекта, созданного из класса. Примером такой ситуации может быть случай, когда классу необходимо знать количество объектов, которые созданы на основе этого класса. Определение счетчика для отслеживания количества созданных объектов как переменной экземпляра не решает проблему. Каждый созданный объект будет иметь свое поле счетчика. Какой счетчик следует обновлять? Решение проблемы в том, чтобы объявить поле счетчика как static
(статическое). Такое поле называется статической переменной. Оно принадлежит классу, а не какому-то объекту класса. Статическая переменная инициализируется, когда загружается в память класс на этапе выполнения.
Аналогично класс может иметь статические методы, которые принадлежат только классу, а не объектам класса.
Статические переменные и статические методы также известны как статические члены и отличаются от членов экземпляра в описании класса ключевым словом static
в своем объявлении.
На рис. 1.4 показана диаграмма класса CharStack
. Она дополнена двумя статическими членами, которые подчеркнуты. Дополненное описание класса CharStack
дается в примере 1.2. Поле счетчика объявлено как статическая переменная в строке (1). На этапе загрузки в память под него выделяется место, и оно инициализируется значением по умолчанию 0. Каждый раз, когда создается объект класса CharStack
, выполняется конструктор из строки (3). В конструкторе происходит явное увеличение счетчика класса. Метод getInstanceCount()
в строке (2) — это статический метод, принадлежащий классу. При вызове он возвращает значение счетчика.
// Имя исходного файла: CharStack.java
public class CharStack {
// Статическая переменная
private static int counter; // (1)
// Статический метод
public static int getInstanceCount() { // (2)
return counter;
}
// Переменные экземпляра
private char[] stackArray; // Массив для хранения символов
private int topOfStack; // Вершина стека
// Теперь конструктор увеличивает счетчик для каждого созданного объекта.
public CharStack(int capacity) { // (3)
stackArray = new char[capacity];
topOfStack = -1;
counter++;
}
// Методы экземпляра
public void push(char element) {
stackArray[++topOfStack] = element;
}
public char pop() {
return stackArray[topOfStack--];
}
public char peek() {
return stackArray[topOfStack];
}
public boolean isEmpty() {
return topOfStack < 0;
}
public boolean isFull() {
return topOfStack == stackArray.length - 1;
}
}
Клиенты могут обратиться к статическим членам класса, используя имя класса. Следующий код вызывает метод getInstanceCount()
класса CharStack
.
// Имя класса для вызова статического метода
int count = CharStack.getInstanceCount();
Статические члены также доступны через ссылки на объекты.
CharStack stack1 = new CharStack(10);
int count1 = stack1.getInstanceCount(); // Вызов статического метода
Статические члены в классе могут быть доступны как по имени класса, так и через ссылки на объекты, но члены экземпляра могут быть доступны только через ссылки на объекты.
Вызовы методов | Терминология для членов класса |