/**
* Returns a canonical representation for the string object.
* <p>
* A pool of strings, initially empty, is maintained privately by the
* class {@code String}.
* <p>
* When the intern method is invoked, if the pool already contains a
* string equal to this {@code String} object as determined by
* the {@link #equals(Object)} method, then the string from the pool is
* returned. Otherwise, this {@code String} object is added to the
* pool and a reference to this {@code String} object is returned.
* <p>
* It follows that for any two strings {@code s} and {@code t},
* {@code s.intern() == t.intern()} is {@code true}
* if and only if {@code s.equals(t)} is {@code true}.
* <p>
* All literal strings and string-valued constant expressions are
* interned. String literals are defined in section 3.10.5 of the
* <cite>The Java™ Language Specification</cite>.
*
* @return a string that has the same contents as this string, but is
* guaranteed to be from a pool of unique strings.
*/
public native String intern();
- intern方法用來(lái)返回常量池中的某字符串,如果常量池中已經(jīng)存在該字符串,則直接返回常量池中該對(duì)象的引用较沪。否則,則常量池中加入該對(duì)象失仁,然后返回引用尸曼。
String設(shè)計(jì)成不可變的原因
- 字符串常量池的需要。字符串常量池的誕生可以提高效率萄焦,減少內(nèi)存分配控轿。String的不可變,常量池可以很容易的被管理和優(yōu)化拂封。
- 安全性考慮茬射。字符串使用的場(chǎng)景很多,設(shè)計(jì)成不可變的可以有效的防止字符串被有意或無(wú)意的被篡改冒签。
- 作為HashMap在抛、HashTable等hash類型key的必要。因?yàn)镾tring被設(shè)計(jì)成不可變的萧恕,JVM底層很容易在緩存String對(duì)象的時(shí)候緩存其hsahCode刚梭,這樣在執(zhí)行效率上會(huì)大大提升肠阱。
創(chuàng)建字符串
- 直接使用雙引號(hào)創(chuàng)建字符串
- 判斷這個(gè)常量是否存在于常量池
- 如果存在,判斷這個(gè)常量是存在的引用還是常量
- 如果是引用朴读,則返回引用地址指向的堆空間對(duì)象
- 如果是常量屹徘,則直接返回常量池常量
- 如果不存在
- 在常量池中先創(chuàng)建該常量,并返回此常量
String s1 = "hello"; // 在常量池中創(chuàng)建常量
String s2 = "hello"; // 直接返回已經(jīng)存在的常量
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true
System.out.println(s1.equals(s2)); // true
String s1 = new String("hello"); // 在堆上創(chuàng)建字符串對(duì)象
s1.intern(); // 在常量池中創(chuàng)建對(duì)象的引用
String s2 = "hello"; // 常量池中存在該常量衅金,直接返回該引用指向的堆空間對(duì)象
String s1 = new String("hello").intern();
String s2 = "hello";
System.out.println(s1 == s2); // true
System.out.println(s1.equals(s2)); // true
- new String();
- 首先在堆上創(chuàng)建對(duì)象
- 然后判斷常量池上是否存在字符串的字面量
- 如果不存在噪伊,在常量池中創(chuàng)建常量
- 如果存在,不做任何操作
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
String s1 = new String("hello").intern();
String s2 = new String("hello").intern();
System.out.println(s1 == s2); // true
System.out.println(s1.equals(s2)); // true
String s1 = new String("hello").intern();
String s2 = "hello";
System.out.println(s1 == s2); // true
System.out.println(s1.equals(s2)); // true
/**
* Returns the string representation of the {@code Object} argument.
*
* @param obj an {@code Object}.
* @return if the argument is {@code null}, then a string equal to
* {@code "null"}; otherwise, the value of
* {@code obj.toString()} is returned.
* @see java.lang.Object#toString()
*/
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
String s1 = String.valueOf("hello");
String s2 = "hello";
System.out.println(s1 == s2); // true
System.out.println(s1.equals(s2)); // true
String s1 = String.valueOf("hello");
String s2 = String.valueOf("hello");
System.out.println(s1 == s2); // true
System.out.println(s1.equals(s2)); // true
String s1 = String.valueOf("hello");
String s2 = new String("hello").intern();
System.out.println(s1 == s2); // true
System.out.println(s1.equals(s2)); // truee