Статическая ошибка инициализатора, если она помещена перед объявлением
Я заметил кое-что в статических инициализаторах, которые могут быть ошибкой в 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.Использование не на левой стороне назначения.
Использование через простое имя.
C является самым внутренним классом или интерфейсом, включающим использование.
Так что, если использование находится слева от присвоения, то это законно, так как второе больше не выполняется.