常量池分类
- 静态常量池:即*.class文件中的常量池,class文件中的常量池不单单包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。这种常量池主要用于存放两大类常量:字面量(例如定义为final的变量,文本字符等等)、符号引用量,符号引用则属于编译原理方面的概念,包括了以下三种类型的常量:
- 类和接口的全限定名
- 字段名称和描述符
- 方法名称和描述符
- 运行时常量池: 运行时常量池相对于CLass文件常量池的另一个重要特征是具有动态性,Java语言并不要求常量必定只有编译期才能产生,也就是并不是预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中。String的intern()方法会查找在常量池中是否存在一份equal相等的字符串,若是有则返回该字符串的引用,若是没有则添加本身的字符串进入常量池。
String 常量池举例
- 直接使用双引号声明出来的 String 对象会直接存储在常量池中。
- 使用new关键字建立String的对象不会存储在常量池中.
- 若是不是用双引号声明的 String 对象,可使用 String 提供的 intern 方法。String.intern() 是一个 Native 方法,它的做用是:若是运行时常量池中已经包含一个等于此 String 对象内容的字符串,则返回常量池中该字符串的引用;若是没有,则在常量池中建立与此 String 内容相同的字符串,并返回常量池中建立的字符串的引用。
与intern有关的比较例子:缓存
注意点:性能
- == 比较的是内存地址 , equals比较的是值
- 字符串拼接的时候:变量+变量 和 直接用字符串+字符串拼接是不同的,前一种会建立个新的对象。
- 咱们在使用字符串的时候应尽可能避免多个字符串拼接,由于这样会从新建立对象。若是须要改变字符串的话,可使用 StringBuilder 或者 StringBuffer。
其余常量池
使用常量池的好处
避免了频繁的建立和销毁对象影响系统的性能,实现了对象的共享,同时也能够节省存储空间,相同的对象占用同一个内存。cdn