描述
String內(nèi)部是final修飾的char[]。下文定義方法獲取String內(nèi)部char[]的hashCode,驗證不同的String對象內(nèi)部char[]是否一致
代碼
private static int showStringInternalCharArrayHashCode(String s) {
Field value = null;
try {
value = String.class.getDeclaredField("value");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
if (value != null) {
value.setAccessible(true);
try {
return value.get(s).hashCode();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return 0;
}
public static void main(String[] args) {
String a = "abc";
String b = "abc";
String c = new String("abc");
System.out.println("a.value:" + showStringInternalCharArrayHashCode(a));
System.out.println("b.value:" + showStringInternalCharArrayHashCode(b));
System.out.println("c.value:" + showStringInternalCharArrayHashCode(c));
System.out.println("a:" + System.identityHashCode(a));
System.out.println("b:" + System.identityHashCode(b));
System.out.println("c:" + System.identityHashCode(c));
// a.value:1595428806
// b.value:1595428806
// c.value:1595428806
// a:1072408673
// b:1072408673
// c:1531448569
}
由結(jié)果看出變量a、b、c各自的內(nèi)部char[]是同一個數(shù)組。a和b是因為從常量池中取出字符串,該字符串本就是同一個對象。c是因為String構(gòu)造函數(shù)中將入?yún)⒌腸har[]賦值給對象。可以從字節(jié)碼中看出。
// #2定位到類常量池,在定位到字符串常量池中常量推送至操作數(shù)棧頂,
0: ldc #2 // String abc
// 存儲變量到局部變量表下標(biāo)1處
2: astore_1
3: ldc #2 // String abc
5: astore_2
// 堆中創(chuàng)建對象,對象引用推入棧頂
6: new #3 // class java/lang/String
// 復(fù)制棧頂元素
9: dup
// 常量池中常量推入棧頂
10: ldc #2 // String abc
// 調(diào)用構(gòu)造函數(shù)初始化,參數(shù)對象引用和常量
12: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
// 對象創(chuàng)建完畢存儲到局部變量表下標(biāo)3處
15: astore_3
public static void main(String[] args) {
String a = "abc";
String b = "aabc".substring(1);
System.out.println("a.value:" + showStringInternalCharArrayHashCode(a));
System.out.println("b.value:" + showStringInternalCharArrayHashCode(b));
System.out.println("a:" + System.identityHashCode(a));
System.out.println("b:" + System.identityHashCode(b));
b = b.intern();
System.out.println("a.value:" + showStringInternalCharArrayHashCode(a));
System.out.println("b.value:" + showStringInternalCharArrayHashCode(b));
System.out.println("a:" + System.identityHashCode(a));
System.out.println("b:" + System.identityHashCode(b));
// a.value:1595428806
// b.value:1072408673
// a:1531448569
// b:1867083167
// a.value:1595428806
// b.value:1595428806
// a:1531448569
// b:1531448569
}
由結(jié)果看出,變量a、b不是同一個對象,內(nèi)部char[]也不是同一個數(shù)組。調(diào)用intern()后,a、b變成同一個對象了。
引用
https://dzone.com/articles/java-string-tutorials
https://dzone.com/articles/string-memory-internals