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

Константы и переменные времени компиляции

Документация на языке Java гласит: "Если примитивный тип или строка определяется как константа и значение известно во время компиляции, компилятор заменяет имя константы всюду в коде своим значением. Это называется компиляцией, постоянной времени".

Итак, я понимаю, что если у нас есть кусок кода:

private final int x = 10;

Затем компилятор заменит каждое вхождение "x" в коде буквой "10". Но скажем, предположим, что константа инициализируется значением во время выполнения,

private final int x = getX(); // here getX() returns an integer value at run-time.

Будет ли какое-либо снижение производительности (насколько ничтожно мало) его можно сравнить с константой времени компиляции?

Другой вопрос заключается в следующем:

private int y = 10; // here y is not final

обрабатывается компилятором так же, как компилятор времени компиляции?

EDIT: Наконец, я понимаю из ответов:

  • final static означает постоянную времени компиляции
  • just final означает его константу, но инициализируется во время выполнения
  • just static означает инициализацию во время выполнения
  • без final является переменной и не будет считаться константой.

Правильно ли я понимаю?

4b9b3361

Ответ 1

Постоянная времени компиляции должна быть:

  • объявлено окончательным
  • примитив или строка
  • инициализировано в декларации
  • инициализировано с постоянным выражением

Итак, private final int x = getX(); не является константой.

К второму вопросу private int y = 10; не является постоянным (в данном случае не конечным), поэтому оптимизатор не может быть уверен, что значение не изменится в будущем. Поэтому он не может оптимизировать его так же хорошо, как постоянное значение. Ответ: Нет, он не обрабатывается так же, как константа времени компиляции.

Ответ 2

Ключевое слово final означает, что переменная будет инициализирована один раз и только один раз. Действительная константа должна быть объявлена ​​static. Таким образом, ни один из ваших примеров не компилируется как константы. Тем не менее последнее ключевое слово сообщает вам (и компилятору), что ваши переменные будут инициализированы только один раз (в конструкторе или буквально). Если вам нужны их значения, назначенные во время компиляции, ваши поля должны быть статическими.

Производительность на самом деле не так впечатлена, но имейте в виду, что примитивные типы неизменяемы, как только вы их создали, она будет удерживать это значение в памяти до тех пор, пока сборщик мусора не удалит его. Итак, если у вас есть переменная y = 1;, а затем вы меняете ее на y = 2; в памяти, JVM будет иметь оба значения, но ваша переменная будет "указывать" на последнюю.

private int y = 10;//здесь y не является окончательным

обрабатывается компилятором так же, как компилятор времени компиляции?

Нет. Это переменная экземпляра, созданная, инициализированная используемой во время выполнения.

Ответ 3

На некоторых машинах может быть очень небольшое снижение производительности для private final int x = getX();, поскольку это будет включать по крайней мере один вызов метода (помимо того факта, что это не константа времени компиляции), но, как вы сказали, это будет ничтожно, так зачем беспокоиться?

Что касается второго вопроса: y не является окончательным и, следовательно, не является константой времени компиляции, поскольку она может меняться во время выполнения.

Ответ 4

private final int x = getX(); Будет вызываться при первом объявлении вашего объекта. Производительность "drop" будет зависеть от getX(), но это не то, что нужно для создания узкого места.