这篇文章上讲解的知识点你全搞明白了,Java中的字符串你就彻底理解了。
即String Pool,但是JVM中对应的类是StringTable,底层实现是一个hashtable,看代码
class StringTable : public Hashtable<oop, mtSymbol> { ……
Key的生成方式
1、通过String的内容+长度生成hash值 2、将hash值转为key hashValue = hash_string(name, len); index = hash_to_index(hashValue); // Pick hashing algorithm unsigned int StringTable::hash_string(const jchar* s, int len) { return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) : java_lang_String::hash_code(s, len); } // Bucket handling int hash_to_index(unsigned int full_hash) { int h = full_hash % _table_size; assert(h >= 0 && h < _table_size, "Illegal hash value"); return h; }
Value的生成方式
将Java的String类的实例instanceOopDesc封装成HashtableEntry HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string()); add_entry(index, entry); template <class T, MEMFLAGS F> HashtableEntry<T, F>* Hashtable<T, F>::new_entry(unsigned int hashValue, T obj) { HashtableEntry<T, F>* entry; entry = (HashtableEntry<T, F>*)BasicHashtable<F>::new_entry(hashValue); entry->set_literal(obj); return entry; }
String类重写了hashcode方法
public int hashCode() { int h = this.hash; if (h == 0 && this.value.length > 0) { char[] val = this.value; for(int i = 0; i < this.value.length; ++i) { h = 31 * h + val[i]; } this.hash = h; } return h; }可以看出String的hashcode与String的内容是有关系的,因此下面的代码的hashcode是相等的
public class TestHashcode { public static void main(String[] args) { String s1 = "11"; String s2 = new String("11"); System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); } }
双引号
new String
两个双引号
两个new String
双引号 + 双引号
public class TestString_5 { public static void main(String[] args) { } public static void test2() { String s1 = "1"; String s2 = "1"; String s = s1 + s2; } } 0 ldc #2 <1> 2 astore_0 3 ldc #2 <1> 5 astore_1 6 new #3 <java/lang/StringBuilder> 9 dup 10 invokespecial #4 <java/lang/StringBuilder.<init>> 13 aload_0 14 invokevirtual #5 <java/lang/StringBuilder.append> 17 aload_1 18 invokevirtual #5 <java/lang/StringBuilder.append> 21 invokevirtual #6 <java/lang/StringBuilder.toString> 24 astore_2 25 return
双引号 + new String
public class TestString_6 { public static void main(String[] args) { } public static void test2() { String s1 = "1"; String s2 = new String("1"); String s = s1 + s2; } } 0 ldc #2 <1> 2 astore_0 3 new #3 <java/lang/String> 6 dup 7 ldc #2 <1> 9 invokespecial #4 <java/lang/String.<init>> 12 astore_1 13 new #5 <java/lang/StringBuilder> 16 dup 17 invokespecial #6 <java/lang/StringBuilder.<init>> 20 aload_0 21 invokevirtual #7 <java/lang/StringBuilder.append> 24 aload_1 25 invokevirtual #7 <java/lang/StringBuilder.append> 28 invokevirtual #8 <java/lang/StringBuilder.toString> 31 astore_2 32 return
常量池中有就直接返回
常量池中没有就创建一个,然后返回
1、这句代码创建了几个对象?为什么?
String s1 = new String("子牙真帅");
2、这句代码创建了几个对象?为什么?
String s2 = "子牙" + "子牙";
3、这句代码创建了几个对象?为什么?
String s2 = "子牙" + new String("真帅");
4、将实例的intern代码的四个内存图画出来