Почему не является константой времени компиляции?

Итак, если у меня есть static final Object CONSTANT = null, по какой-то причине, если я ссылаюсь на это в другом фрагменте кода, например doSomething(CONSTANT), он не будет вставлен в код во время компиляции. Поэтому вместо doSomething(null) после компиляции это будет doSomething(CONSTANT).

Ответ 1

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

Смысл этого в том, что экземпляр Object (в общем случае) имеет семантически значимый идентификатор объекта, который отличает его от других экземпляров Object. Этот идентификатор объекта не может быть закодирован в файле класса... или, по крайней мере, он не может быть закодирован с текущими форматами файлов классов. (И если бы это было возможно, возникли бы все другие проблемы...)

Значение null может (теоретически) рассматриваться как частный случай, за исключением того, что нет большой точки. В частности, вы не можете использовать null в любом из контекстов, где требуется "постоянная времени компиляции" (или выгодная) с лингвистической точки зрения. Например:

  • Вы не можете иметь null как выражение case.
  • Так как == для ссылочных типов не является постоянным выражением, вы не можете использовать его для идиомы "условной компиляции" Java с участием if с постоянным выражением как условие. (И кроме того null == null не является полезным условием...)

Что касается включения, в то время как "константа" не может быть встроена в байт-коды (из-за правил JLS о том, что такое "постоянное выражение" ), оптимизатор компилятора JIT будет разрешен для этого, и может на самом деле это... если есть ощутимые преимущества в производительности.

Ссылка:

Ответ 2

В вашем случае CONSTANT не является постоянной времени компиляции.

Константа времени компиляции является константой, и ее значение известно во время компиляции и он не изменится дальше, тогда компилятор заменяет постоянное имя везде в коде с его значением.

Обычно примитивный тип или строковый литерал, объявленный с final, обрабатывается компилятором как константа времени компиляции. Пример:

final int a=10;
final String constant ="this is compile time const";

Эти обе являются константами времени компиляции, которые мы можем использовать выражения константы времени компиляции в методах ярлыков операторов switch

Пример для констант времени без компиляции

final String xyz = new String("this is not a compile time const");

здесь xyz string object не является константой времени компиляции. Поскольку этот строковый объект xyz будет создаваться во время выполнения, и здесь компилятор знает о ссылке только не строковый объект.

То же самое применимо к вашему статическому окончательному объекту CONSTANT = null

Подтверждение JLS

Тип нулевого литерала - это нулевой тип, его значение является нулевой ссылкой.