Compile Time Constant

独自空忆成欢 提交于 2020-01-23 17:13:28

问题


I understood what a compile time constant rule is from Compile-time constants and variables.

  1. declared as final
  2. have a primitive or String type
  3. initialized at the same time as the declaration
  4. initialized with constant expression

final int x = 5;

But I fail to understand why below code doesn't:

final int x;
x = 5;

The only difference is of third point above. How initialization on different line instead of same line makes a difference.


回答1:


Case 1 final int x = 5;

public static void main(String[] args) {
    final int x = 5;
}

The bytecode generated is:

  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

Case 2 final int x; x = 5;

public static void main(String[] args) {
    final int x;
    x = 5;
}

The bytecode generated is:

  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

As you can see there is no difference between the 2 cases, except for the line numbers.

In fact in an ide such as InteliJ you will see the prompt (as a light bulb) to join the 2 lines of case 2, to 1 line like case 1.

If you read all the answers and comments in the link you provided,
you will be more confused than wiser about this.
It's all about terminology and in this case not documented terminology.

This is an excerpt of one of the answers in that link:

The JLS does not contain the phrase compile-time constant.
However, programmers often use the terms compile-time constant and constant interchangeably.

Now for the case of how the compiler uses the 2 cases.
If you add this line at the end of both methods:

System.out.println(x);


the bytecode generated is:
for case 1

GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ICONST_5
INVOKEVIRTUAL java/io/PrintStream.println (I)V

and for case 2

GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ILOAD 1
INVOKEVIRTUAL java/io/PrintStream.println (I)V

There is a difference in the 2nd case: ILOAD 1 instead of ICONST_5.
Meaning in the 1st case x was replaced by 5 and in the 2nd case it was not and the value of x was recalled (loaded) to execute the statement.




回答2:


From JLS Sec 4.12.4:

constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).

If the variable is declared without being initialized, it is by definition not a constant variable, even if the value you eventually assign to it is a constant expression.



来源:https://stackoverflow.com/questions/53897620/compile-time-constant

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!