当前位置: 首页 > 面试题库 >

为什么String.intern()在Oracle JDK 1.7中表现不同?

葛言
2023-03-14
问题内容

这是一个Java代码段:

public class TestIntern {
    public static void main(String[] argvs){
        String s1 = new StringBuilder("ja").append("va").toString();
        String s2 = new StringBuilder("go").append("lang").toString();
        System.out.println(s1 == s1.intern());
        System.out.println(s2 == s2.intern());
    }
}

而且它根据不同的JDK表现不同

在Oracle JDK 1.7中的输出是:

false
true

在OpenJDK 1.6中的输出也是:

false
true

但是在Oracle JDK 1.6中,输出为:

false
false

如此String#intern方法的JavaDoc所指示

 * When the intern method is invoked, if the pool already contains a
 * string equal to this <code>String</code> object as determined by
 * the {@link #equals(Object)} method, then the string from the pool is
 * returned. Otherwise, this <code>String</code> object is added to the
 * pool and a reference to this <code>String</code> object is returned.
                           ~~~~
                             And what does *this* here mean? the string object
                             in the heap or in the string pool? if it returns 
                             object in the heap the out put should be:

                             true
                             true
                             otherwise should *always* be:

                             false
                             false
                             Am I right?

输出:

true
true

应该可以预期,但是三个JDK都不会产生这种情况。以及Oracle JDK1.6为什么提供:

false
false

结果是?

我认为在OracleJDK 1.7和openJDK 1.6 中,字符串池中必须有一些 保留 的字符串,它们是什么?是否有文档指定所有 保留的
字符串?真的很困惑。


问题答案:

无论s1.intern()收益s1或其他一些String对象取决于它发现在实习字符串池。如果String池中已经有其他对象,intern()则将返回该其他对象;否则会将String引用的对象s1放入池中并返回该对象。

问题不在于不同的Java版本的行为不同,而是当您运行测试时池恰好包含不同的东西。我并不感到特别惊奇的是,Oracle JDK 1.7和openJDK
1.6中的池恰好已经包含字符串,"java"但不包含字符串"golang"



 类似资料:
  • 问题内容: 在有人质疑使用的事实之前,我先说一下,出于内存和性能的原因,我需要在特定的应用程序中使用它。[1] 因此,到目前为止,我一直使用并假定这是最有效的方法。但是,自古以来我就注意到它是软件的瓶颈。[2] 然后,就在最近,我试图用一个巨大的映射替换,在该映射中放置/获取字符串,以便每次获得唯一的实例。我以为这会慢一些…但是事实恰恰相反!它快得多了!通过推送/轮询地图(实现完全相同)来替换,可

  • 让这种方法本土化背后的逻辑是什么? 与仅使用哈希图制作内嵌字符串池相比,有什么优势? 它看起来有点奇怪,但在非本机代码中似乎很容易做到: 那么为什么是本机代码呢?

  • 以下代码在使用JDK 8和JDK 9运行时有不同的结果。 在JDK 8(版本1.8.0_172)下,代码打印: 但是使用JDK 9(版本9.0.1),代码返回: 我已经检查了两个JDK版本,它们是正确的。为什么代码会产生不同的结果?我的程序有什么问题吗?

  • 我现在想要一个数据结构,就像一个有索引的Deque。因此,它应该有O(1)在前面和后面添加和删除元素,以及O(1)基于索引访问元素。这并不难想象一个适合这种情况的设置。 ArrayDeque似乎是一个自然的选择。但是,ArrayDeque不实现List。由于底层数据结构是一个数组,是否有充分的理由不允许索引? 还有,更实用的是,有人知道有哪个图书馆在做我想做的事情吗。据我所知,Apache Com

  • 问题内容: 我试图了解某些“魔术”行为的根本原因,但我无法完全解释,而从阅读ReactJS源代码中看不出来。 当响应输入中的事件而同步调用该方法时,所有操作均按预期进行。输入的“新”值已经存在,因此DOM实际上并未更新。这是非常理想的,因为这意味着光标不会跳到输入框的末尾。 但是,当运行具有完全相同结构但 异步 调用的组件时,输入的“新”值似乎不存在,从而导致ReactJS实际触摸DOM,这将导致

  • 问题内容: 我知道有两种在Java中创建String的方法: 通过第一种方式,Java一定会在字符串池中创建一个String对象并对其进行引用。(假设“ aaa”以前不在池中。) 使用第二种方法,将在堆中创建一个对象,但是jvm还会在字符串池中创建一个对象吗? 在这篇关于Java的字符串池的问题中,@ Jesper说: 如果您这样做: 那么池中将有一个String对象,一个代表文字“ abc”的>