Java常量池详解

  • 什么是常量池


什么是常量池

java开发中,经常会用到字符串,字符串的创建有两种方式:

  • String str = “abc”;
  • String str = new String(“abc”);
    这两种方式的创建过程是不同的,java中存量字面量和符号引用的概念,字面量是指由字母、数值组成的字符串或者数值常量。第一种方式的等号右边的"abc"就是一种字面量。符号引用主要包括三类:
  • 类和接口的权限定名
  • 字段的名称和描述符
  • 方法的名称和描述符

常量池中的静态数据只有在运行时才会把信息加载到内存中,才会有具体的分配内存地址,当运行时这些静态数据就变成了运行时常量池的数据。

#字符串常量池
设计的目的:

  1. 字符串的创建和创建其他对象时一样的,耗费高昂的时间和空间代价,作为基础的数据类型,频繁的创建字符串,极大的影响了系统的性能。
  2. jvm为了提高性能和减少内存的使用,在实例化的时候做了优化,为字符串创建字符串常量池,类似于开辟了缓存区;创建字符串时先在字符串常量池中查找是否已经存在,存在话,则返回实例的引用值,如果不存在,则在池中创建并返回创建的实例的引用。

#三种字符串的操作

  1. String s1 = “abc”;
    先到字符串常量池中查询是否存在,存在则直接返回常量的地址,如果不存在,那么则在常量池中创建一个常量,然后在返回常量地址
  2. String s1 = new String(“abc”);
    这种方式会保证在字符串常量池和堆中同时存在,但是会返回堆中实例的引用地址。过程是:先拿字面量"abc"到字符串常量池查询是否存在,如果不存的话,则在常量池中创建一个字面量实力,然后在堆中创建一个实例,最后返回堆中实例的地址。
  3. String s1 = new String(“abc”);
    String s2 = s1.intern();
    String的intern方法是一个native方法,调用intern方法时,如果常量池中存在时,直接返回常量池的字符串引用。否则将返回s1的地址。