【发布时间】:2020-06-27 06:19:18
【问题描述】:
代码:
String s1 = "Hello";
String s2 = new String("Hello");
Field declaredField = String.class.getDeclaredField("value");
declaredField.setAccessible(true);
byte[] arr1 = (byte[])declaredField.get(s1);
byte[] arr2 = (byte[])declaredField.get(s2);
现在,s1 == s2 = False,arr1== arr2 = True。
我的问题是对象是如何存储在内存中的。
第一行确实在池中创建了一个新的字符串类型对象。第二行确实将它作为常规对象在堆上创建
但是底层的 byte[] 数组是一样的。这让我想到,JVM 会以某种方式检查这样一个现有的 byte[] 是否已经存在,并将所有引用指向同一个数组。这是否意味着无论我们使用字面量还是 new 关键字,底层数组都缓存在池中?
所以 s = "something" 在池上创建了一个新的 String 类型对象以及一个保存数据的底层数组 - 它也在池上创建。
s = new String("something") -> 在堆上创建 String 类型的对象,但底层数组仍然存储在池中/如果已经存在,则只是创建一个引用。
我的理解正确吗?
注意:这不是关于常量池存储在哪里、实习生如何工作、创建了多少对象或使用不同的创建技术/使用实习生如何影响 == 结果的问题。
【问题讨论】:
-
JVM 不会尝试对数据进行“重复数据删除”。
-
@ch 没有完全得到您对上下文的回答,请您再详细一点。谢谢
标签: java string string-literals