Статическая ошибка инициализатора, если она помещена перед объявлением

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

Так что, если использование находится слева от присвоения, то это законно, так как второе больше не выполняется.

Другие вопросы по тегам