Инициализация статического конечного поля из статического инициализатора

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

Сначала я подумал, что это ошибка Eclipse:

Ошибка Eclipse?

Я также состоял в некотором недостатке знаний, потому что статические инициализаторы не являются моим повседневным делом. Но о чудо, это работает без квалификатора класса, как и ожидалось:

Недостаток знаний?

Чтобы завершить серию тестов, я попробовал в bash:

Черт!

вызывая тот же результат.

Это приводит меня к последнему вопросу:

Есть ли причина запрещать квалификатор класса при доступе к статическим конечным полям из статических блоков инициализатора? Потому что объявляющий класс раньше не был инициализирован?


person Franz Ebner    schedule 13.08.2014    source источник
comment
@ Shail016 прав, простите за это, ребята..   -  person Franz Ebner    schedule 13.08.2014


Ответы (2)


Чтобы инициализировать конечную переменную в блоке инициализации, следует использовать простое имя переменной. то есть только имя переменной без каких-либо квалификаторов.

Это указано в спецификации языка Java, как показано ниже.

«Аналогично, каждая пустая конечная переменная должна быть присвоена не более одного раза; она должна быть определенно неназначенной, когда происходит присвоение ей. Такое присвоение происходит тогда и только тогда, когда либо простое имя переменной, либо ее простое имя, дополненное этим, находится в левой части оператора присваивания. Компилятор Java должен выполнить специальный консервативный анализ потока, чтобы убедиться, что для каждого присваивания пустой конечной переменной переменная определенно не назначено до присваивания; в противном случае должна произойти ошибка времени компиляции».

person Ranuka    schedule 13.08.2014

На самом деле вы можете инициализировать статическое поле из статического инициализатора.

Но я думаю (я не уверен), что у вас другая проблема. Проблема здесь в том, что вы (согласно компилятору) пытаетесь назначить поле final. Однако ваше истинное намерение состоит не в том, чтобы назначить его. Вы пытаетесь инициализировать его. Но компилятор этого не понимает.

Когда вы вызываете что-то вроде Test.I, компилятор будет думать, что вы пытаетесь изменить статическую переменную, которая может быть предварительно инициализирована (то есть из статического инициализатора). Компилятор не настолько умен, чтобы видеть, что вы на самом деле инициализируете свою переменную, он просто интерпретирует, что вы назначаете статическую переменную из класса, будь то Test или это Foo.

Однако, если вы вызываете его без классификатора класса, компилятор знает, что вы пытаетесь изменить свою собственную статическую переменную и в статическом инициализаторе, поэтому операция безопасна для финального поле.

Пожалуйста, я надеюсь, что я достаточно ясно выразился, и, пожалуйста, обратите внимание, что я не уверен в этом поведении.

person Matias Cicero    schedule 13.08.2014