Итак, если у меня есть 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
Тип нулевого литерала - это нулевой тип, его значение является нулевой ссылкой.