String底层怎么在JVM内存中存储

String s1 = “11”; 这句内存中怎么执行

首先java中的String 是通过char[] 存储的(这是基础知识了)

那么先研究一下char[] 是怎么存储的

public class CharArray {

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

        change(arr);

        System.out.println(arr[0]);

        while (true);
    }

    public static void change(char[] arr) {
        arr[0] = 'A';
    }
}

在这里插入图片描述

在这里插入图片描述

通过HSDB 可以 看出来,其实char[] 在底层C++ 中就是 TypeArrKlass
可以参考我的另一篇博客
Java中的类怎么在JVM(C++)中存在?类的加载过程

字符串常量池

即String Pool,但是JVM中对应的类是StringTable,底层实现是一个hashtable,看代码

class StringTable : public Hashtable<oop, mtSymbol> {
……

index 的生成方式

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 相当于java中HashMap中的Entry<Key,Value>

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

回到正题

String s1 = “11”;
等价于
String s1 = new String(“11”)

  1. 从字符串常量池中按照key=“11”;找HashtableEntry,如果找到了直接返回HashtableEntry的Value。因为HashtableEntry的Value就指向了String类的实例instanceOopDesc
  2. 如果没有找到,则会创建String类的实例instanceOopDesc,并将其封装到字符串常量池。
  3. 由于"11"最终保存在char[],所以还会创建TypeArrKlass的OopDesc,然后将这个OopDesc赋值给String的instanceOopDesc;

图解
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七层汉堡王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值