这篇文章上讲解的知识点你全搞明白了,Java中的字符串你就彻底理解了。

tech2025-05-18  12

这篇文章上讲解的知识点你全搞明白了,Java中的字符串你就彻底理解了。

 

字符数组的存储方式

public static void main(String[] args) { char[] arr = new char[]{'1', '2'}; while (true); }

 

字符串常量池

 

即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()

 

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()); } }

 

不同方式创建字符串在JVM中的存在形式

 

双引号

 

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

intern做了什么

 

常量池中有就直接返回

常量池中没有就创建一个,然后返回

 

练习

 

1、这句代码创建了几个对象?为什么?

String s1 = new String("子牙真帅");

 

2、这句代码创建了几个对象?为什么?

String s2 = "子牙" + "子牙";

 

3、这句代码创建了几个对象?为什么?

String s2 = "子牙" + new String("真帅");

 

4、将实例的intern代码的四个内存图画出来

最新回复(0)