java.lang.String的intern()方法
"abc".intern()方法的返回值還是字符串"abc",表面上看起來好像這個方法沒什么用處。但實際上,它做了個小動作:
檢查字符串池里是否存在"abc"這么一個字符串,如果存在,就返回池里的字符串;如果不存在,該方法會把"abc"添加到字符串池中,然后再返回它的引用。
我們做個測試:
String str1 = "a";
String str2 = "bc";
String str3 = "a"+"bc";
String str4 = str1+str2;
System.out.println(str3==str4);
str4 = (str1+str2).intern();
System.out.println(str3==str4);
輸出的結果將會是:
false
true
JDK的api文檔是這么解釋的:
=======================================================================
返回字符串對象的規范化表示形式。
一個初始時為空的字符串池,它由類 String 私有地維護。
當調用 intern 方法時,如果池已經包含一個等于此 String 對象的字符串(該對象由 equals(Object) 方法確定),則返回池中的字符串。否則,將此 String 對象添加到池中,并且返回此 String 對象的引用。
它遵循對于任何兩個字符串 s 和 t,當且僅當 s.equals(t) 為 true 時,s.intern() == t.intern() 才為 true。
所有字面值字符串和字符串賦值常量表達式都是內部的。字符串字面值在《Java Language Specification》的 §3.10.5 中已定義。
返回:
一個字符串,內容與此字符串相同,但它保證來自字符串池中。
=======================================================================
字符串字面池指的是常量池.
字符串對象的創建方式有兩種
如下:
String s1 = new String(""); //第一種
String s2 = ""; //第二種
第一種始終不會入池的.
第二種要看情況而定(等號右邊如果是常量則入池,非常量則不入池)
例:
String s3 = "a" + "b"; //"a"是常量,"b"是常量,常量+常量=常量,所以會入池.
String s4 = s1 + "b"; //s1是變量,"b"是常量,變量+常量!=常量,所以不會入池.
//那引用s4所指的對象在哪里創建??????
一旦入池的話,就會先查找池中有無此對象.如果有此對象,則讓對象引用指向此對象;如果無此對象,則先創建此對象,再讓對象引用指向此對象.
例:
String s5 = "abc"; //先在池中查找有無"abc"對象,如果有,則讓s5指向此對象;如果池中無"abc"對象,則在池中創建一個"abc"對象,然后讓s5指向該對象.補充一下:
看了字節碼后,發現
String str ="a"+"b";
完全等同于
String str="ab";
-----------------------------------------------------------------------------------------------------------------------------
Java虛擬機有一個字符串池,保存著幾乎所有的字符串常量。字符串表達式總是指向字符串池中的一個對象。
public class Test...{
public static void main(String[] args)...{
String s1=new String("abc");
String s2="abc";//放入String池里
String s3=new String("abc");
System.out.println(s1==s2);//false
System.out.println(s1==s3);//false
System.out.println(s3==s2);//false
System.out.println(s1==s1.intern());//s1.intern()到String池里找,而s1是在堆中所以返回false
System.out.println(s2==s2.intern());//true
System.out.println(s1.intern()==s3.intern());//兩個字符串同時到String池里查找,返回true
//以下三個都放到String池
String hello="hello";
String hel="hel";
String lo="lo";
System.out.println(hello=="hel"+"lo");//字符串相加以后,會到String池里找,有不產生,所以返回true
System.out.println(hello=="hello");//直接到String池里找,返回true
System.out.println(hello=="hel"+lo);//字符串加一個引用,將產生一個新的對象,所以返回false
System.out.println(hello==(hel+lo));//類似上面,返回false
System.out.println(hello==(hel+lo).intern());//產生新的對象,但是有intern()方法,將到String池中找,返回true
}
}

2

3

4

5

6

7

8

9

10

11

37

38

39

40

41

42

//主要是看類A是否自己實現了hashcode和equals方法
43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

73

74

75

76

77

78

79

80
