Подтвердить что ты не робот

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

Рассмотрим этот фрагмент кода:

public static void main(String[] args) {
    int z1 = 0;
    final int z2 = 0;
    System.out.println(false ? z1 : 'X');
    System.out.println(false ? z2 : 'X');
}

При запуске этого кода я ожидаю увидеть две X в консоли. Однако реальный вывод:

88
X

Если мы посмотрим на спецификации Java относительно тройного оператора, мы обнаружили, что

Если один из операндов имеет тип T, где T является байтом, коротким или char, а другой операнд является константным выражением типа int, значение которого представляется в типе T, то тип условного выражения T.

Итак, первый вывод рассматривает 'X' char как int, поэтому он печатает 88.

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

4b9b3361

Ответ 1

Во втором случае z2 считается константным выражением, потому что это конечная переменная типа int.

Из раздел 4.12.4:

Мы вызываем переменную примитивного типа или типа String, которая является окончательной и инициализируется постоянным выражением времени компиляции (§15.28) постоянной переменной. Независимо от того, является ли переменная постоянной или нет, она может иметь последствия для инициализации класса (§12.4.1), бинарной совместимости (§13.1, §13.4.9) и определенного назначения (§16).

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

z1 не является конечной переменной (хотя ничто не присваивает ему значение), поэтому она не является постоянной переменной и, следовательно, не является постоянным выражением, поэтому абзац, который вы цитируете из спецификации, не применяется.