Ошибка статического инициализатора при размещении перед объявлением
Я заметил что-то в статических инициализаторах, которые могут быть ошибкой в javac. Я построил сценарий, в котором я могу назначить переменной значение, но не прочитать это значение обратно.
два примера ниже, первый компилируется нормально, второй получает ошибку при попытке прочитать значение из tmp, но по какой-то причине назначение значения tmp разрешено. Я мог бы понять, если бы он не мог ни читать, ни писать в переменную, так как tmp объявлен после статического инициализатор, но ошибка только на одном из них не имеет для меня смысла.
//Compiles Successfully:
public class Script
{
public static Object tmp;
static
{
tmp = new Object();
System.out.println(tmp);
}
}
//error only on the read but not the assignment
public class Script
{
static
{
tmp = new Object();
System.out.println(tmp);
}
public static Object tmp;
}
чтобы подчеркнуть этот момент дальше, это успешно компилируется.
public class Script
{
static
{
tmp = new Object();
}
public static Object tmp;
}
1 ответов
кажется, это определено в спецификации (см. JLS 8.3.2.3):
объявление члена должно появиться текстуально, прежде чем оно используется, только если элемент является экземпляром (соответственно статическим) поля класс или интерфейс C и все следующие условия:
использование происходит в инициализаторе переменной экземпляра (соответственно статическом) C или в инициализаторе экземпляра (соответственно статическом)
С.использование не находится в левой части назначения.
использование через простое имя.
C-самый внутренний класс или интерфейс, заключающий использование.
поэтому, если использование находится в левой части задания, то это законно, так как второй больше не выполняется.