public static void main(String[] args) {
        String a = new StringBuilder("Jav").toString();
        a.intern();
        String c = "Jav";
        System.out.println(a == c);  //false
    }
    public static void main(String[] args) {
        String a = new StringBuilder("Ja").append("v").toString();
        a.intern();
        String c = "Jav";
        System.out.println(a == c);  //true
    }

enter image description here

我不明白为什么第一个打印的是假的,而第二个打印的是真的.我认为这应该是真的,因为在调用intern方法后,a的引用将被写入字符串池,而c将指向a的引用.有人能解释一下区别吗?谢谢!

我的JDK版本:OpenJDK 17.0.7

顺便说一句,我在使用StringBuffer时也得到了同样的结果.

推荐答案

TL;灾难恢复和解决方案

重要的区别是前"Jav"个文字/实习生的位置.

intern() returns你是典范参考.如果规范引用已存在,则不会更新它.

因此,您需要将a.intern();更改为a = a.intern();:

public static void main(String[] args) {
    String a = new StringBuilder("Jav").toString();
    a = a.intern();
    String c = "Jav";
    System.out.println(a == c); //this is true now
}

这些例子为什么不同,又是如何不同的

在您的第二个示例中,==返回true,因为StringBuilder返回的String是第一个intern()调用中的规范引用,并且String字面值被延迟解析并给出.

然后,文字会给出与您已经拥有的对象相同的规范引用.

在第一个示例中,已经存在具有该内容的规范String,因此intern()方法只返回existing规范String,而不是使当前的String成为规范.

进一步 comments

有关您的代码的更详细分析,请参阅@Nidheesh R‘S answer.

正如@Jorn提到的in the comments,无论如何你不应该需要String#intern,你也不应该在String上使用==.

此外,依赖于这种行为是脆弱的.如果你正在使用像GraalVMnative-image这样的工具,使用不同的JVM,或者可能是Project Leyden个S冷凝器中的一些,这样的事情可能会有一点不同.

Java相关问答推荐

Spring Webocket:尽管凭据设置为False,但MLhttpsify和Fetch请求之间的CORS行为存在差异

scanner 如何在执行hasNextLine一次后重新读取整个文件?

Java inline Double条件和值解装箱崩溃

JavaFX Maven Assembly插件一直打包到错误的JDK版本

FALSE:它应该在什么时候使用?

查找剩余的枚举

如何从JNI方法正确调用NSOpenPanel以在正确的线程上运行?

Spring @Value default无法计算表达式

自定义批注的外推属性值

在Frege中,我如何将一个字符串安全地转换为一个可能的Int?

基于配置switch 的@Controller的条件摄取

删除打印语句会影响功能...腐败在起作用?

如何生成指定范围内的11位序列号?

Java在操作多个属性和锁定锁对象时使用同步和易失性

项目react 堆中doOnComplete()和Subscribe()的第三个参数之间的差异

在Oracle db中,当我们提供字符串而不是数字时,比较是如何工作的?

没有Google Play服务,Firebase Auth无法工作

如何在Selenium上继续使用最新的WebDriver版本

如何使用Jackson读取以方括号开头的JSON?

java.util.LinkedList()是如何成为MutableList的实例的?