Java中使用==比较static final String是否始终返回true?
package foo.library; public class Consts { public static final String FOO = "foo"; }
package bar.code; public class codeFuncs { public String func1() { return FOO; } if(func1() == FOO) .... }
(该常量来自作为依赖引入的类库。)
Java是否保证
func1() == FOO始终返回true? 结论:只要Consts.FOO是当前代码中的这种编译期常量,func1() == FOO会始终返回true,具体原因如下:
- 对于用字符串字面量赋值的
static final String,Java编译器会执行常量内联:所有引用Consts.FOO的地方,都会被直接替换成字面量"foo"。 - JVM规范明确要求,所有字符串字面量都会被自动驻留:相同的字面量会被存储在字符串常量池中,所有指向该字面量的引用,都会指向同一个对象实例。
所以func1()返回的是内联后的"foo",条件判断里的FOO也是内联后的"foo",两者指向常量池中的同一个对象,用==比较引用地址自然会返回true。
不存在“编译器内联但不驻留”的情况——字符串字面量的驻留是JVM的标准行为,不管是直接编写的字面量还是编译器内联生成的,都会纳入驻留机制。
唯一的例外场景:如果Consts.FOO不是编译期常量(比如初始值是通过方法调用获取的,如public static final String FOO = getFoo();),编译器不会做内联,此时FOO指向运行时创建的字符串对象,若未手动驻留,==比较可能返回false,但当前代码完全不涉及这种情况。
内容的提问来源于stack exchange,提问作者Ariel
相关产品推荐
相关产品推荐

