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

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

 

字符数组的存储方式

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

    while (true);
}

image.png

image.png

 

字符串常量池

 

即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中的存在形式

 

双引号

image.png

 

new String

image.png

 

两个双引号

 

image.png

两个new String

 

image.png

拼接字符串底层是如何实现的

 

双引号 + 双引号

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做了什么

 

常量池中有就直接返回

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

 

image.png

练习

 

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

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

 

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

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

 

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

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

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值