字符串池的实现有一个前提条件:String对象是不可变的。因为这样可以保证多个引用可以同事指向字符串池中的同一个对象。如果字符串是可变的,那么一个引用操作改变了对象的值,对其他引用会有影响,这样显然是不合理的。
在工作中,
String
类是我们使用频率非常高的一种对象类型。
JVM
为了提升性能和减少内存开销,避免字符串的重复创建,其维护了一块特殊的内存空间,这就是我们今天要讨论的核心,即
字符串池(
String Pool
)
。字符串池由
String
类私有的维护。
字符串池的优缺点
:字符串池的优点就是避免了相同内容的字符串的创建,节省了内存,省去了创建相同字符串的时间,同时提升了性能;另一方面,字符串池的缺点就是牺牲了JVM在常量池中遍历对象所需要的时间,不过其时间成本相比而言比较低。
字符串池是Java为了重用
String
对象而设置的一个缓存池,Java1.7之前设置在方法区上,保存的是String对象;Java1.7之后设置在堆上,保存的是
String
对象的引用,
String
对象本身存在于堆上的其他位置。下文中以Java1.7之后的情况为标准。
String
String
String
继续上面的例子。当JVM在解释String m = #1时,它已经从运行时常量池拿到了相应的UTF8序列,接下来,它会在字符串池中寻找和这个UTF8序列对应的String对象,并把这个对象的引用赋值给m。你可能会好奇这个String被创建的时机,根据R大的
这篇文章
,在这条语句所在的类被加载时,如果字符串池中已经存在对应的对象了,那么就什么都不做,如果不存在,就会创建一个对应的String对象,并把其引用放入池中。
除了字符串池,
Integer
、
Long
等Wrapper类型也有自己的缓存池,比如
Integer
会缓存从-128~127的
Integer
对象,当使用字面量赋值或者
Integer.valueOf()
时,如果池中存在相应的对象,就会返回池中的对象,只有当池中没有时才会在堆上创建新对象。
Integer
Long
Integer
Integer
Integer.valueOf()
不过,和字符串池不同的时,这些Wrapper池不会像字符串池一样可以增长,也就是池中的对象数目是固定的,Integer池中只会有-128~127。
版权声明:本文为weixin_69620038原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。