字符串常量池和intern
字符串常量池是Java语言中的一种机制,旨在节省空间和提高性能。它是一个内存区域,所有的Java类共享这个池子。字符串常量池的设计思想是为了解决字符串的频繁创建问题,减少内存开销和提高性能。
在Java中,字符串是不可变的,可以共享运行时实例创建的全局字符串常量池中。字符串常量池维护一个引用表,每个唯一的字符串对象都有一个对应的引用。这样,字符串常量池中的字符串不会被垃圾收集器回收。
字符串常量池的实现机制是通过StringTable实现的。StringTable有点类似于Hashtable,里面保存了字符串的引用。Java可以根据字符串的hashCode找到对应的entry,如果没有冲突,它可能只是一个entry,如果有冲突,它可能是一个entry链表,然后Java再遍历entry链表,匹配引用对应的字符串,如果找得到字符串,返回引用,如果找不到字符串,会把字符串放到常量池中,并把引用保存到StringTable里。
在Java中,有两种创建字符串对象的方式:直接使用双引号声明出来的String对象会直接存储在常量池中。如果不是用双引号声明的String对象,可以使用String提供的intern方法。intern方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中。
在Java中,字符串常量池存在于方法区中。方法区是静态区,跟堆一样,被所有的线程共享。方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
了解字符串常量池的位置是非常重要的。Java中的堆、栈、方法区都是不同的内存区域。堆存储的是对象,每个对象都包含一个与之对应的class。栈每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用。方法区静态区,跟堆一样,被所有的线程共享。
在Java中,字符串常量池的使用可以提高性能和减少内存开销。Java提供了两种创建字符串对象的方式,可以根据实际情况选择合适的方式创建字符串对象。