String类中关于不同对象字符串内容相等时的解释

目录

一.问题的引入

二.字符串常量池

1.引入字符串常量池的原因

2.需要了解的三种常量池

 3.详解关于字符串对象问题

(1)在字节码中查看

 (2)问题​

 (3)问题图解

(4)关于字符串常量池的注意事项

(5)总结


一.问题的引入

对于下面例子中,我们可以知道它们的结果是怎样的

 字符串是不可变的,可能我们会想这几个字符串的内容都一样会不会都是相等的。

 在这里我们可能会想到对于new的对象,它们的地址肯定是不相同的,但是对于str1和str2也是字符串类型的对象。

我们再通过debug来看它们的地址有什么区别。

 要想了解这几个字符串在Java中是如何进行引用的,就需要知道常量池以及字符串常量池。

二.字符串常量池

1.引入字符串常量池的原因

对于重复的字符串来说,Java为了使运行速度更快,更节省内存,所以通过字符串常量池来进行管理字符串。

例子:比如吃瓜子的瓜子皮扔进垃圾桶,方法1:每吃一个,去垃圾桶扔一次;方法2:将瓜子皮放到手中,当手中满了,再去垃圾桶扔。这里的方法2的效率就很高,相当于池化技术。

2.需要了解的三种常量池

(1) Class文件常量池:每个.Java源文件编译后生成.Class文件中会保存当前类中的字面常量以及符号信息.


(2)运行时常量池:在.Class文件被加载时,.Class文件中的常量池被加载到内存中称为运行时常量池,运行时常量池每个类都有一份.

(3)字符串常量池.

 常量池中的内容管理相当于使数组一样,需要使用时就像访问数组中的索引一样。

 3.详解关于字符串对象问题

关于问题的引入中str1,str2,str3,str4在字节码中常量池详情

(1)在字节码中查看

关于其中

 (2)问题

 (3)问题图解

在字节码文件加载时“aaaa”常量串已经创建好并加载到了字符串常量池中。

从下图结果我们可以得到关于字符串中内容是如何创建的

这里str1和str2存放的是“aaaa”对象的引用,而str3和str3中是创建一个新的对象,从而将原本"aaaa"对象中的hash和value拷贝一份给当前对象。 

 这里面设计到了数据结构中的哈希表管理数据,对于哈希表中的每一个内容,又通过单链表来进行管理,单链表中每一个结点中有该结点的哈希码,string内容(内容地址),和下一个结点地址,如果没有就为null.

(4)关于字符串常量池的注意事项

1. 在JVM中字符串常量池只有一份,是全局共享的。当多个类同时运行时,使用的是同一份字符串常量池。
2. 刚开始字符串常量池是空的,随着程序不断运行,字符串常量池中元素会越来越多。
3. 当类加载时,字节码文件中的常量池也被加载到JVM中,称为运行时常量池,同时会将其中的字符串常量保存在字符串常量池中。
4. 字符串常量池中的内容:一部分来自运行时常量池,一部分来自程序动态添加。


(5)总结

1.通过上面图解可知,只要是new的对象,都是唯一存在的。

2.可以发现关于实例化对象的时候,直接实例化,只会开辟一块内存空间,而使用new来实例化使用两块内存空间,所以直接实例化会节省内存空间。

 3.我们知道对于实例化时还有一种是使用字符数组,但是字符数组不是直接加入到常量池中,我们可以进行验证

 

 这里是因为ch字符数组会在堆上创建,new字符串对象的时候,会将堆上ch的内容拷贝到str5对象中的value中,和字符串常量中的对应的value不是同一份,所以结果会不想等。

4.intern()方法的使用

该方法的作用是手动将创建的String对象添加到常量池中。且该方法是一个本地方法。

对于使用字符数组创建字符串对象,我们可以使用该方法手动将该对象添加到字符串常量池中。

具体使用:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值