Постоянная времени компиляции - PullRequest
0 голосов
/ 22 декабря 2018

Я понял, что такое правило постоянной времени компиляции из Константы и переменные времени компиляции .

  1. , объявленные как окончательные
  2. , имеют примитив или тип String
  3. инициализируется одновременно с объявлением
  4. , инициализируется константным выражением

final int x = 5;

Но я не понимаю, почему приведенный ниже код не:

final int x;
x = 5;

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

Ответы [ 2 ]

0 голосов
/ 23 декабря 2018

С JLS Sec 4.12.4 :

A константа - это конечная переменная типа примитива или типа String, которая инициализируется константойвыражение (§15.28).

Если переменная объявлена ​​без инициализации, она по определению не является константной переменной, даже если значение, которое вы в конечном итоге назначаете ей, является константным выражением.

0 голосов
/ 22 декабря 2018

Дело 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 было вызвано (загружено) для выполнения оператора.

...