在Java程序中,类似于:1, 2, 3,3.14,"hello"等字面类型的常量经常频繁使用,为了使程序的运行速度更快、
更节省内存,Java为8种基本数据类型和String类都提供了常量池。
1.为什么要发明常量池
为了节省存储空间以及程序的运行效率,Java中引入了:
-
Class文件常量池 :每个.Java源文件编译后生成.Class文件中会保存当前类中的字面常量以及符号信息
-
运行时常量池 :在.Class文件被加载时,.Class文件中的常量池被加载到内存中称为运行时常量池,运行时常
量池每个类都有一份
- 字符串常量池
此处简单了解下,后等我学到JVM再和兄弟们进行补充,现在我们就先学字符串常量池。
2.字符串常量池
java
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
String s4 = new String("hello");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
System.out.println(s3 == s4); // false
}
前面我们知道 equals 和 == 的区别,==如果不是基本数据类型是需要比较内存地址值的(相当于C里面的指针)
如果直接对其赋值就会在堆上找到这个字符串将内存地址给到虚拟机栈,但是当new一个新对象时,会首先产生新的内存地址值
3.inturn方法
当new一个新对象时,不会进入字符常量池,inturn就是将该字符串进入常量池的方法
未使用inturn前
java
public static void main3(String[] args) {
char[] ch = {'a','b','c'};
String str = new String(ch);
String ss = "abc";
System.out.println(str == ss);//flase
}
使用后
java
public static void main4(String[] args) {
char[] ch = {'a','b','c'};
String str = new String(ch);
str.intern();
String ss = "abc";
System.out.println(str == ss);//true
}
在堆上是这样实现的
inturn的作用就是将0X12哈希存的0X98和"abc"字符串链接一起