常量池详解

常量池详解

Class常量池与运行时常量池

  • Class常量池可以理解为字节码文件中的资源仓库,字节码文件包括除了魔数、主次版本号、接口、方法等描述信息外,还有一项信息就是常量池,用于存放编译期间生成的各种字面量和符号引用
  • 问题: 什么是运行时常量池、Class常量池、全局常量池
    • Class常量池: 存放编译期间生成的各种字面量和符号引用
    • 运行时常量池: JVM启动的时候,将常量池的静态数据加载到方法区中去
    • 全局常量池: 存放的是字符串的引用值,JVM只有一份
  • 问题: 什么是字面量
    • 字面量就是变量的值,比如String a = “abc”,"abc"就是字面量
  • 问题: 什么是符号引用
    • 方法名和描述符
    • 字段的名称和描述符
    • 类和接口名称
  • 问题: 什么是动态链接
    • 程序运行期间,将符号引用转变为直接引用,比如方法中调用方法,JVM解析的时候会对被调用的方法名指向一个内存地址,通过这个地址找到对应的方法,最常见的就是多态,有不同的实现,只有到运行的时候才知道
    • 举个例子: 比如math.compute()
      • 静态的时候compute()就是符号引用,加载到内存后就有内存地址,这个地址就是符号引用在内存中的地址,叫直接引用,根据这个内存地址可以找到这个方法在方法区里的代码信息,类似于函数指针

字符串常量池

  • 注意: 在JDK6中,字符串常量池在运行时常量池中,在JDK7放在了堆中
  • 字符串常量池类似于缓存池,在创建任何一个字符串之前,都会去这个常量池查一下,有就直接返回,没有就新建
    • 例如: String s = new String(“a”),会生成两个引用,一个字符串常量池中,一个在堆中

JDK7+常量池

image.png

  • 直接赋值字符串: 常量池中没有就创建对象,有匹配后直接返回

    String s = "abc";
    

    这种创建的字符串对象,只会在常量池中,创建对象的时候,JVM会先去常量池中通过equals方法,判断是否有相同的对象,如果有,返回它在常量池中的引用,如果没有,就在常量池中创建一个对象,返回它的引用

  • new String(): 如果常量池和堆中都有这个对象,就直接把堆中引用返回,如果常量池有这个字符串对象,就只要在堆中创建一个字符串对象,如果不存在,得在字符串和堆中都创建该对象,最后把堆中内存返回

    String s = new String("abc");
    

    这种方式保证常量池和堆中都有这个对象,没有就创建,最后返回堆内存中的对象引用(生成两个引用)

    先检查字符串常量池中是否存在这个字符串,

    不存在,就在常量池中创建一个字符串对象,然后再去堆内存中创建一个字符串对象

    存在,就直接在堆内存中创建一个对象.

    最后将堆内存中的引用返回.

  • intern()

    String s1 = new String("abc");
    String s2 = s1.intern();
    System.out.println(s1 == s2);  // JDK6->false JDK7以上->true
    

    String中的intern方法是一个 native 的方法,当调用 intern方法时,如果常量池已经包含一个等于此String对象的字符串(用equals(object)方法确定),则返回池中的字符串。

    否则,将intern返回的引用指向当前字符串 s1(JDK6版本需要将 s1 复制到字符串常量池里)

八种基本类型的包装类和对象池

  • java中基本类型的包装类的大部分都实现了常量池技术(严格来说应该叫对象池,并且在堆上),这些类包含
    • Byte
    • Short
    • Integer
    • Long
    • Character
    • Boolean
  • 以上这六种,除了Boolean类型,其他五种对应-128到127才可使用对象池,即对象不负责创建和管理 > 127 的对象。因为这种小的数用到的概率比较大
  • 另外两种浮点数类型的包装类没有实现对象池技术: Double、 Float
  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫吹过的柚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值