Дело 1 final int x = 5;
public static void main(String[] args) {
final int x = 5;
}
Сгенерированный байт-код:
public static main([Ljava/lang/String;)V
L0
LINENUMBER 3 L0
ICONST_5
ISTORE 1
L1
LINENUMBER 4 L1
RETURN
L2
LOCALVARIABLE args [Ljava/lang/String; L0 L2 0
LOCALVARIABLE x I L1 L2 1
MAXSTACK = 1
MAXLOCALS = 2
Случай 2 final int x; x = 5;
public static void main(String[] args) {
final int x;
x = 5;
}
Сгенерированный байт-код:
public static main([Ljava/lang/String;)V
L0
LINENUMBER 4 L0
ICONST_5
ISTORE 1
L1
LINENUMBER 5 L1
RETURN
L2
LOCALVARIABLE args [Ljava/lang/String; L0 L2 0
LOCALVARIABLE x I L1 L2 1
MAXSTACK = 1
MAXLOCALS = 2
Как видите, между этими двумя случаями нет никакой разницы, за исключением номеров строк.На самом деле, в идеале, таком как InteliJ, вы увидите приглашение (в виде лампочки) соединить 2 строки варианта 2 с 1 строкой, как случай 1.Если вы прочитали все ответы и комментарии по указанной вами ссылке,вы будете более смущены, чем мудрее об этом.Все дело в терминологии и в данном случае не документированная терминология.Это отрывок одного из ответов по этой ссылке:
JLS не содержит константу времени компиляции фразы.Тем не менее, программисты часто используют термины постоянная времени компиляции и взаимозаменяемо.
Теперь для случая, когда компилятор использует 2 случая.Если вы добавите эту строку в конце обоих методов:
System.out.println(x);
сгенерированный байт-код:для кейс 1
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ICONST_5
INVOKEVIRTUAL java/io/PrintStream.println (I)V
и для кейс 2
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ILOAD 1
INVOKEVIRTUAL java/io/PrintStream.println (I)V
Существует разница во 2-м случае: ILOAD 1
вместоICONST_5
.Значение в 1-м случае x
было заменено на 5, а во 2-м - нет, и значение x
было вызвано (загружено) для выполнения оператора.