Java - 告诉String是否被实习?

时间:2011-02-03 08:26:35

标签: java string

所以这里的问题很简单:有没有办法判断Java中的String是否被实现?我的猜测是否定的,但我想知道是否有人知道的更好。

4 个答案:

答案 0 :(得分:15)

您可以了解String是否被拦截的唯一方法是致电intern()并检查其是否自行返回:

boolean hasBeenInternedBefore = myString.intern() == myString;

这显然有一个缺点,就是String在没有实习之前实习。

部分偏离主题,有一种方法可以使用Interner interfaceGuava使用显式池进行“自定义”实习(使用Interners class公开的实现)。这样做的好处是能够让Interner本身(以及游戏池)在不再被引用时被垃圾收集。

答案 1 :(得分:2)

有一种方法可以检查特定String对象是否已被实现,但如果这些内容尚未实现,则会将内容插入到字符串池中。创建一个具有相同内容的新String对象,实习对象并与原始对象进行比较:

new String(s).intern() == s

这是因为new String(s) != s的事实。考虑每种可能的情况:

  1. s在字符串池中实现。 new String(s)s的内容相同,因此调用它intern()将返回s。表达式的结果为true
  2. s未在字符串池中实现,但另一个相等的String对象是 - 我们称之为s2intern()将返回s2,因此表达式的结果为false
  3. s未在字符串池中实现,并且任何String都不等于它。在这种情况下,new String(s)将被插入到字符串池中,这很可能会修改字符串池。由于此String对象与s不同,因此表达式的结果为false
  4. 因此,上面的表达式将正确测试s是否在字符串池中实现。以下测试证明了这一点:

    public static void main(String[] args) {
        String interned = new String(new char[] { 'i', 'n', 't' }).intern();
        String notInterned = new String(new char[] { 'n', 'o', 't' });
        System.out.println("Case 1: " + wasInterned(interned));
        System.out.println("Case 2: " + wasInterned(new String(interned)));
        System.out.println("Case 3: " + wasInterned(notInterned));
    }
    
    public static boolean wasInterned(String s) {
        return new String(s).intern() == s;
    }
    

    运行时,输出为:

     Case 1: true
     Case 2: false
     Case 3: false
    

答案 2 :(得分:0)

我们不能在实习字符串的存储库中查看,并且无法获取所有实习字符串的集合。

测试,如果给定的字符串已被实现已经产生了一个很好的困境(顺便说一下测量的常见问题):测量本身可能会影响实习字符串的存储库;)

要测试,如果存储库包含给定的String,我们需要将该String与(最坏情况下)该存储库中的所有字符串进行比较 - 具有风险,JVM在之前实现此引用String 开始比较...虽然在测试之前没有实现字符串,但会返回true;)

但除此之外,我没有看到任何实际用途,知道虚拟机是否已经实现了字符串。实习很便宜,如果需要就可以实习。 (如果有实际用途,String类将提供原生测试方法)

答案 3 :(得分:0)

没有。一般来说,您不需要检查 - 只需intern他们确定或不依赖实习。如果您需要实习或非实习字符串进行测试或试验,您可以制作它们:

实习:

s = someArbitraryString.intern();

非实习:

s = new String(someArbitraryString);