Jeffrey的博客 Jeffrey的博客

左脑编程,右脑写诗

目录
Java字符串常量池String Pool的理解
/    

Java字符串常量池String Pool的理解

Java中String是一个非常特殊的数据类型,在学习JVM虚拟机的时候,才真正意识到为了让String类型在运行过程中速度更快、更节省内存,才提供了字符串常量池的概念。

概念

字符串常量池(String Pool)保存所欲字符串字面量(literal strings),这些字面量在编译时期就确定,不仅如此,还可以使用String的intern()方法在运行时添加到常量池中。

常量池的使用主要有两种方法:

  • 直接使用双引号声明出来的String对象会直接存储到常量池中。
  • 使用String提供的intern()方法时,会查询字符串常量池中是否存在当前字符,如果不存在则将当前字符串放入常量池中。

String、StringBuffer、StringBuilder

这是String的另一个知识点,这里只是提一下一笔带过。

  1. 可变性
  • String 不可变
  • StringBuffer 和 StringBuilder 可变
  1. 线程安全性
  • String 不可变,因此是线程安全的
  • StringBuilder 不是线程安全的
  • StringBuffer 是线程安全的,内部使用 synchronized 进行同步

String Pool示例(JDK1.8)

这里要特别注意,此处以JDK1.8为例,因为在JDK1.7之前常量池在Perm区,而在JDK1.7之后常量池在Java Heap区,所以所看到的运行结果会有所不同。

String s1 = "ss";		// 在常量池上创建常量s1
String s2 = "ss";		// 直接放回已存在的常量
System.out.println(s1 == s2);	// true
String s1 = new String("ss");	// 在堆上创建对象
String s2 = new String("ss");	// 在堆上创建对象
System.out.println(s1 == s2);	// false
String s1 = "ss1" + "ss2"	// 在常量池上创建常量ss1、ss2、ss1ss2
String s2 = "ss1ss2";
String s3 = "ss1" + "ss2";
System.out.println(s2 == s3);  // true
String s1 = new String("ss1") + new String("ss2");	// 在堆上创建对象ss1、ss2和ss1ss2,在常量池上创建常量ss1和ss2
s1.intern();
String s2 = "ss1" + "ss2";
System.out.println(s1 == s2);	// true
String s1 = new String("ss") + new String("ss1");	// 常量ss不存在,所以第一步在常量池中创建了常量ss
String s2 = new String("s") + new String("s");	// 创建对象ss
System.out.println(s2 == s2.intern());		// false
System.out.println(s1 == s1.intern());		// true
String s1 = "ss1ss2";
String s2 = "ss1" + new String("ss2");
System.out.println(s1 == s2.intern());		// true
String s1 = "ss1ss2";
String s2 = "ss1" + new String("ss2");
System.out.println(s1 == s2.intern());		// true
System.out.println(s2 == s2.intern());		// false

规律:
1.new String在堆上创建字符串对象。
2.通过字面量赋值创建字符串(如:String str=”1”)时,会先在常量池中查找是否存在相同的字符串,若存在,则将栈中的引用直接指向该字符串;若不存在,则在常量池中生成一个字符串,再将栈中的引用指向该字符串。
3.常量字符串的+“”操作,编译阶段直接会合成为一个字符串。如String str=”JA”+”VA”,在编译阶段会直接合并成语句String str=”JAVA”,于是会去常量池中查找是否存在”JAVA”,从而进行创建或引用。


标题:Java字符串常量池String Pool的理解
作者:Jeffrey