2017-08-09 28 views
13

我对实习生功能有点困惑。我有以下代码:Java实习生功能

public class InternTest{ 

    public static void main(String args[]){ 
      String s1 = "ANEK"; 
      String s2 = new String("ANEK"); 
      String s3 = s2.intern(); 
      System.out.println(s3 == s1); // True 

      String s11 = "ANEK".concat("SINGH"); 
      String s22 = s11.intern(); 
      System.out.println(s11 == s22); // True 

      String s4 = "nat".concat("ive"); 
      String s5 = s4.intern(); 
      System.out.println(s4 == s5); // True 

      String s33 = "ma".concat("in"); 
      String s44 = s33.intern(); 
      System.out.println(s33 == s44); // false 

      String s331 = "ja".concat("va"); 
      String s441 = s331.intern(); 
      System.out.println(s331 == s441); // false 
    } 
} 

我的问题是关于输出。在第三种情况下,它给了我的真实性,但在第四和第五种情况下,它给了我虚假。我能否知道这些输出背后的原因是什么?我不能得出结论,它为java保留字或关键词提供了假,因为当我尝试使用en时,它给出了真实性,但是通过te它给了我假。任何人都可以告诉我为什么?

+1

@YCF_L实习生功能给我的规范表示字符串.. –

+3

为什么它是重复的?这不是关于字符串比较的问题,而是关于'intern'的使用 – ByeBye

+0

字符串实习是一种仅存储每个不同字符串值的一个副本的方法,它必须是不可变的。 在Java中,String类具有公共方法intern(),它返回字符串对象的规范表示形式。 Java的String类私有维护一个字符串池,其中字符串文字被自动实现。而当你比较字符串,你应该使用等于不是== –

回答

13

那么你得到的输出是你做的,因为javamain字符串已经在池中 - 当你启动应用程序时,还有很多其他的类被加载,其中一些已经加入了这些字符串(在你的代码到达之前)

我期望native也 - 但我猜不是,意思是没有其他人实习它。

这引起了一些注意(我没有想到),所以我想我会扩大一点。假如你这样做:

String left = new String(new char[] { 'h', 'e', 'y' }); 
    String right = left.intern(); 
    System.out.println(left == right); 

这将打印true在前面的String池,因为“嘿”不是,并通过我们的left.intern()增加。在另一方面:

String left = new String(new char[] { 'j', 'a', 'v', 'a' }); 
String right = left.intern(); 
System.out.println(left == right); 

打印false因为“Java”的已经在游泳池当我们叫left.intern

+0

我发现有趣的事情是我在类中定义的任何方法的名称包含'main'方法(我没有尝试其他类的方法)也已经在String池中。 – Eran

+0

@Eran使'intern'更像是一个调试目的的方法......我无法想象一个地方我明确想要使用它..这是btw,因为解析类的方式发生的可能性最大 – Eugene

7

让我们看看的intern()文档:

如果池已经包含一个字符串等于由equals(Object)方法,则返回从池中字符串确定此字符串对象。否则,将此String对象添加到池中,并返回对此String对象的引用。

这意味着,如果已经有与返回字符串池中的给定值的字符串,否则返回的实际字符串。 由于前三个字符串不在池中,实际字符串 - s2,s11s4在添加到池后返回,因此它是相同的引用。不知何故'main''和''java''已经在池中,并且intern()返回该字符串而不是s33s331(假设s331.intern()用于上次调用)。

尝试这种情况:

String tmp = "ANEKSINGH"; // so this is in the pool 
String s11 = "ANEK".concat("SINGH"); 
String s22 = s11.intern(); 
System.out.println(s11 == s22); // FALSE now 
0

实习生()返回字符串对象的规范表示。 A 字符串池最初为空,由类 字符串私下维护。

当调用实习方法时,如果池已包含等于(Object) 方法所确定的与此String对象相等的 字符串,则返回池中的字符串。否则,此 字符串对象将被添加到池中,并返回对此字符串 对象的引用。

返回true的输出表示字符串存在于字符串池中。

输出将是真实的,如果实习生新创建和使用concated字符串实习生()

例子:

public class InternTest{ 

public static void main(String args[]){ 
    String s1 = "ANEK"; 
    String s2 = (new String("ANEK")).intern(); 
    String s3 = s2.intern(); 
    System.out.println(s3 == s1); // True 

    String s33 = ("ma".concat("in")).intern(); 
    String s44 = s33.intern(); 
    System.out.println(s33 == s44); // True 

    String s331 = ("ja".concat("va")).intern(); 
    String s441 = s33.intern(); 
    System.out.println(s331 == s441); // True 
} 
}