Чтение косвенного состояния Vs.Читать прямое состояние переменной в Java - PullRequest
0 голосов
/ 20 апреля 2019

В следующем коде ошибка компиляции для static переменная j внутри статического блока, как указано в комментарии.

Однако внутри метода все работает нормально m1()

class StaticBlock {
    static {
        m1();
        //compilation fails because variable are in read indirect state
        System.out.println(j);
    }

    static void m1() {
        System.out.println(j);
    }

    static int j = 10;

Я знаю основную причину сбоя компиляции - переменная j находится в состоянии чтения с косвенным доступом.

Мой вопрос: почему при таком поведении мы также можем печатать 0 внутри статического блока, как мы делаем вm1().

Что заставило разработчиков API иметь это несоответствие

1 Ответ

1 голос
/ 20 апреля 2019

Почему такое поведение, мы также можем напечатать 0 внутри статического блока, как мы делаем в m1().

Что заставило разработчиков API иметь это несоответствие

Существуют конкурирующие приоритеты, вращающиеся вокруг простых спецификаций для порядка событий во время инициализации класса, согласованности константных (т.е. final) полей класса, ожиданий программиста и простоты реализации.

Значения константыПоля обеспечивают хорошую отправную точку.Java хотела бы избежать наблюдения значений по умолчанию таких полей и особенно избегать использования их значений по умолчанию при инициализации других переменных класса.Следовательно, они инициализируются первыми, перед статическими инициализаторами или инициализаторами других переменных класса.Они инициализируются в том порядке, в котором они появляются в исходном коде, что является правилом, которое легко понять как людям, так и компиляторам.Но это дает возможность того, что инициализатор одной переменной класса видит значение по умолчанию для другой, что приводит к неожиданным, нежелательным результатам.Поэтому Java указывает, что этот случай должен быть обнаружен и отклонен во время компиляции.

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

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

Наконец, я подчеркиваю, что так называемое «состояние чтения только косвенной записи» является частью сторонней моделикак это все работает.Сама Java не имеет такого понятия - такая вещь как раз и отвергается в пользу простоты, когда речь идет о требованиях к использованию переменных класса статическими методами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...