Случай 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
Как видите, между двумя случаями нет никакой разницы, кроме номеров строк.
На самом деле в ide, таком как 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
было вызвано (загружено) для выполнения оператора .
person
forpas
schedule
22.12.2018
x
. В противном случае не уверен, что не работает для вас! - person Naman   schedule 22.12.2018