Главная » Java » Статические члены

0

Класс содержит члены двух видов: поля и методы. Для каждого из них задается атрибут, определяющий возможности наследования и доступа (private, protected, public или package). Кроме того, каждый из членов при желании можно объявить как static.

Для статического члена создается всего один экземпляр, общий для всего класса, вместо построения его копий в каждом объекте класса. В случае статических переменных (переменных класса), это ровно одна переменная, независимо от того, сколько объектов было создано на основе класса (даже если ни одного). Образцом может служить поле nextID класса Body в приведенном выше примере.

Инициализация статических полей класса происходит до того, как они используются или запускается любой из его методов. В следующем примере метод unset может быть уверен в том, что перед использованием переменной UNSET ей было присвоено значение Double.NaN:

class Value {

public static double UNSET = double.NaN;

private double V;

public void unset() { V = UNSET;

}

// …

}

2.9.1. Блоки статической инициализации

Класс также может содержать блоки статической инициализации, которые присваивают значения статическим полям или выполняют иную необходимую работу. Статический инициализатор оказывается наиболее полезным в тех случаях, когда простой инициализации в объявлении поля недостаточно. Например, создание статического массива часто должно выполняться одновременно с его инициализацией в операторах программы. Приведем пример инициализации небольшого массива с простыми числами:

class Primes {

protected static int[] knownPrimes = new int[4];

static {

knownPrimes[0] = 2;

for(int i = 1; i < knownPrimes.length; i++)

knownPrimes[i] = nextPrime();

}

}

Статическая инициализация внутри класса выполняется в порядке слева направо и сверху вниз. Инициализатор, или статический блок, каждой из статических переменных выполняется перед следующим, начиная от первой строки исходного текста к последней. При этом можно гарантировать, что массив knownPrimes будет создан до выполнения статического блока в нашем примере.

Что произойдет, если статический инициализатор класса X вызывает метод класса Y, а статический инициализатор Y, в свою очередь, вызывает метод из класса X для задания своих статических величин? Подобные циклические инициализации не могут быть надежно выявлены в процессе компиляции, поскольку в момент компиляции X класс Y может еще не существовать. Если возникает подобная ситуация, то статические инициализаторы X выполняются лишь до вызова метода Y. Когда Y, в свою очередь, обратится к методу X, то последний будет выполняться без завершения статической инициализации. Все статические поля X, для которых инициализация не была выполнена, будут иметь значения по умолчанию (false, ‘\u0000’, ноль или null в зависимости от типа).

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

Блок статической инициализации может вызывать методы, возбуждающие исключения, но лишь в том случае, если он готов сам перехватить их все.

2.9.2. Статические методы

Статические методы вызываются для целого класса, а не для каждого конкретного объекта, созданного на его основе. Подобные методы также называются методами класса. Статический метод может выполнять задачи, общие для всех объектов класса, — например, возвращать следующий серийный номер (в нашем примере с плеерами) или

что-нибудь в этом роде.

Статический метод работает лишь со статическими переменными и статическими методами класса. Ссылка this в этом случае не может использоваться, поскольку не определен конкретный объект, для которого вызывается данный метод.

За пределами класса статические методы обычно вызываются через имя класса, а не через ссылку на конкретный объект:

prime = Primes.nextPrime();

knownCnt = Primes.knownPrimes.length;

Упражнение 2.13

Включите в класс Vehicle статический метод, который возвращает максимальное значение идентификатора, использованное на данный момент.

Источник: Арнольд К., Гослинг Д. – Язык программирования Java (1997)

По теме:

  • Комментарии