编译时间常量
Compile Time Constant
我从 Compile-time constants and variables.
了解到什么是编译时间常量规则
- 宣布为最终
- 有原始类型或字符串类型
- 与声明同时初始化
- 用常量表达式初始化
final int x = 5;
但是我不明白为什么下面的代码没有:
final int x;
x = 5;
唯一不同的是上面第三点。
在不同行而不是同一行上进行初始化有何不同。
案例一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
案例二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 的 ide 中,您会看到提示(作为灯泡)将案例 2 的 2 行加入案例 1 中的 1 行。
如果您阅读 link 中的所有答案和评论,您将获得 ided,
对此你会更困惑而不是更明智。
这都是关于术语的,在这种情况下 未记录 术语。
这是 link:
中的一个答案的摘录
The JLS does not contain the phrase compile-time constant.
However, programmers often use the terms compile-time constant and constant
interchangeably.
现在介绍编译器如何使用这两种情况。
如果您在两种方法的末尾添加此行:
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
第二种情况有所不同:ILOAD 1
而不是 ICONST_5
。
意思是在第一种情况下 x
被 5 替换,而在第二种情况下它不是,x
的值被调用(加载)以执行语句。
A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).
如果变量在未初始化的情况下声明,则根据定义它不是常量变量,即使您最终分配给它的值是常量表达式也是如此。
我从 Compile-time constants and variables.
了解到什么是编译时间常量规则- 宣布为最终
- 有原始类型或字符串类型
- 与声明同时初始化
- 用常量表达式初始化
final int x = 5;
但是我不明白为什么下面的代码没有:
final int x;
x = 5;
唯一不同的是上面第三点。 在不同行而不是同一行上进行初始化有何不同。
案例一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
案例二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 的 ide 中,您会看到提示(作为灯泡)将案例 2 的 2 行加入案例 1 中的 1 行。
如果您阅读 link 中的所有答案和评论,您将获得 ided,
对此你会更困惑而不是更明智。
这都是关于术语的,在这种情况下 未记录 术语。
这是 link:
The JLS does not contain the phrase compile-time constant.
However, programmers often use the terms compile-time constant and constant interchangeably.
现在介绍编译器如何使用这两种情况。
如果您在两种方法的末尾添加此行:
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
第二种情况有所不同:ILOAD 1
而不是 ICONST_5
。
意思是在第一种情况下 x
被 5 替换,而在第二种情况下它不是,x
的值被调用(加载)以执行语句。
A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).
如果变量在未初始化的情况下声明,则根据定义它不是常量变量,即使您最终分配给它的值是常量表达式也是如此。