我想寻求建议。
java中编译时评估和运行时评估有什么不同?我认为“评估”是指确定变量的值?
String str = "Hi" + "Bye"
这里,因为有文字值,所以这些值是编译时的评估?它到底是什么意思? JVM 之后做什么? JVM 在堆上分配内存?
String a = "Hi";
String result = a + "hello";
在 JVM 中的运行时进行评估? JVM在堆上分配内存?
谢谢
解释编译时评估和运行时评估
java中编译时评估和运行时评估有什么不同?
正如名字所言。编译时评估是在编译 Java 代码时执行的评估。运行时评估是在程序运行时执行的评估。
我认为“评估”是指确定变量的值?
求值是指确定表达式的值。变量名本身就是一个表达式,但通常它只是较大表达式的一部分。此外,计算表达式的原因不仅仅是为了确定分配给变量的值。
String str = "Hi" + "Bye"
这里,因为有文字值,所以这些值是评估 编译时间?到底是什么意思?
Java 将某些表达式分类为编译时常量表达式。这是可以想象在编译时计算的所有表达式的子集。 Java 源代码中的某些上下文要求使用此类表达式(例如,case
标签的值),并且在这些特定上下文中,Java 实际上要求在编译时对它们进行计算。
String
类型的编译时常量表达式。这意味着该表达式的每次计算都将返回对同一
String
对象的引用,这实际上需要在编译时实际计算 String
类型的 all 编译时常量表达式。原始类型的编译时常量表达式并非如此,但实际上,这些通常也在编译时计算,即使技术上不需要,因为这样做既简单又安全,并且使得生成的类文件更小更快。可能有一些表达式不是 JLS 定义意义上的编译时常量表达式,但仍然可以在编译时计算(但请注意,“可以”对于引用类型比对于原始类型要微妙得多)。 JLS 不禁止在编译时计算这些。
表达式
"Hi" + "Bye"
是 JLS 定义的编译时常量表达式。由于上面讨论的实习要求,它必须在编译时进行评估。
JVM 之后会做什么?JVM 不参与字符串连接的计算。它检索对表示结果的驻留
String
对象的引用,并将其存储在变量
str
中。
JVM
在堆上分配内存?new与任何其他对象一样,表示连接字符串的对象确实存在于堆上。然而,由于使用了 interned 字符串,因此该对象已经存在。不执行
分配。
String a = "Hi";
String result = a + "hello";
在 JVM 中的运行时进行评估? JVM在堆上分配内存?
"Hi"
和“hello”是编译时常量表达式。
a
和 a + "hello"
不是,正如语言规范所定义的那样。尽管编译器可以认为 result
的初始值始终是一个将 equals()
与 "Hihello"
进行比较的字符串,但 JVM 有义务为每次计算 String
时创建一个新的 a + "hello"
对象。它将像任何其他对象一样存在于堆上。它可能会同时将 equals()
与虚拟机中存在的其他 String
对象进行比较,但最初不会有其他引用将 ==
与 result
的值进行比较。