Хотя приведенный пример технически корректен, все же использование ссылки на объект для обращения к статическим полям и методам не рекомендуется, поскольку это усложняет код.
Обращение к статическому полю является корректным независимо оттого, были ли порождены объекты от этого класса и в каком количестве. Например, стартовый метод mainO запускается до того, как программа создаст хотя бы один объект.
Кроме полей и методов, статическими могут быть инициализаторы. Они также называются инициализаторами класса, в отличие от инициализаторов объекта, рассматривавшихся ранее. Их код выполняется один раз во время загрузки класса в память виртуальной машины. Их запись начинается с модификатора static:
Class Human {static {
System.out.println("Class loaded");} }
Если объявление статического поля совмещается с его инициализацией, то поле инициализируется также однократно при загрузке класса. На объявление и применение статических полей накладываются те же ограничения, что и для динамических,— нельзя использовать поле в инициализаторах других полей или в инициализаторах класса до того, как это Иоле объявлено:
class Test { static int а; static {a=5;
// b=7; // Нельзя использовать до объявления!}
static int b=a; }
Это правило распространяется только на обращения к полям по простому имени. Если использовать составное имя, то обращаться к полю можно будет раньше (выше в тексте программы), чем оно будет объявлено:
class Test {static int b=Test.a;
static int a=3;
static {System.out.println("a="+a+'\ b="+b);} }
Если класс будет загружен в систему, на консоли появится текст: а=3,Ь=0
Видно, что поле b при инициализации получило значение по умолчанию поля а, т.е. 0. Затем полю а было присвоено значение 3.
Статические поля также могут быть объявлены как final, это означает, что они должны быть проинициализированы строго один раз и затем уже больше не менять своего значения. Аналогично, статические методы могут быть объявлены как final, а это означает, что их нельзя перекрывать в классах-наследниках.
Для инициализации статических полей можно пользоваться статическими методами и нельзя обращаться к динамическим. Вводят специальные понятия — статический и динамический контексты. К статическому контексту относят статические методы, статические инициализаторы, инициализаторы статических полей. Все остальные части кода имеют динамический контекст.
При выполнении кода в динамическом контексте всегда есть объект, с которым идет работа в данный момент. Например, для динамического метода это объект, у которого он был вызван, и так далее.
Напротив, со статическим контекстом ассоциированных объектов нет. Например, как уже указывалось, стартовый метод main() вызывается в тот момент, когда ни один объект еще не создан. При обращении к статическому методу, например, MyClass.staticMethod(), также может не быть ни одного экземпляра MyClass. Обращаться к статическим мeтoдaм класса Math можно, а создавать его экземпляры нельзя.
А раз нет ассоциированных объектов, то и пользоваться динамичес-1Д1МИ конструкциями нельзя. Можно только ссылаться на статические поля и вызывать статические методы. Либо обращаться к объектам через ссылки на них, полученные в результате вызова конструктора или в качестве аргумента метода и т.п.
class Test {public void processO {}
public static void main(String s[]) {// processO; - ошибка! у какого объекта его вызывать?
Test test = newTestO; test.processO; // так правильно } }