2017-08-09 61 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 
} 
}