String常量池
一、常量池的概念
public static void main(String[] args) {
String s1 = "happy";
String s2 = "happy";
String s3 = new String("happy");
String s4 = new String("happy");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s3 == s4);//false
}
创建的四个字符串互相比较,就会发现,虽然字符内容相同,但是比较结果不同
这里先不考虑用equals,因为equals只比较内容,而我们要考虑的是这些字符串的地址值
-
这段代码:s1和s2引用的是同一个对象,而s3和s4不是
-
Java为八种基本数据类型和String类都提供了常量池,因为有些字面类型的常量会频繁使用,为了提高效率,节省内存
池就是为了提升效率,在一定范围内存储内容,随用随取
二、常见的常量池
1.class文件常量池
- 每个.Java源文件编译后,生成的.Class文件会保存当前类当中的字面常量以及字符信息
2.运行时常量池
- 在.Class文件被加载时,.Class文件中的常量池被加载到内存中,称为运行时常量池(每个类都有)
3.字符串常量池
- 接下来主要介绍
三、字符串常量池(StringTable)
字符串常量池在JVM中是StringTable类,它的本质的一个固定大小的哈希表(HashTable)
在Java8中,字符串常量池的位置在堆中,可以设置大小,有范围限制,最小是1009
1.String的创建过程
-
只要是双引号“ ”引起来的的,都会放在常量池当中
-
先在常量池中查找,是否有当前这个字符串,如果存在,则不会再存
-
因为s1已经存进字符串常量池中,s2就会从常量池中把s1存的取出来。所以s1和s2指的是同一个对象
-
而s3是新创建的一个String对象,这个对象的value指向的是original.value。所以s3和时s1指的不是一个对象
- 只要是new的对象,都是唯一的
2.intern方法
- intern方法是一个native方法
- 手动将创建的String对象添加到常量池
public static void main(String[] args) {
char[] c = {'a','b','c'};
String s1 = new String(c);
// s1.intern();
String s2 = "abc";
System.out.println(s1==s2);//有intern true,没有则是false
}