Java原始数据类型强化学习之常量池

举报
breakDawn 发表于 2020/12/15 17:15:51 2020/12/15
【摘要】 java常量池

Q:常量池的好处?
节省内存空间: 相同字符串常量都是同一个
可使用==做比较,节省运行时间: 常量间==做比较可直接比较地址,不用依次比较字符。


Q: 静态常量池 和动态常量池的区别:
前者一般存放class文件中可以看得到的常量
后者一般是运行中生成的常量, 经典的比如new String(“abcd”).intern() 之后,“abcd”就会被放到常量池中,这并非class文件中能看到的。


Q: 常量池放在哪?
根据之前看虚拟机那本书,说的是放在方法区。
image.png

但是听说java78之后常量池的位置有变化。
可以看这篇博文,底下人吵翻天了,也没看出个确切结论,如果有明确结果的可以评论区告诉我哈: https://blog.csdn.net/wanderlustLee/article/details/80762851
大家自己斟酌。


Q:常量池里的来源,除了class文件,还有什么途径?
A:
运行时常量池中的常量,基本来源于各个class文件中的常量池。
程序运行时,除非手动向常量池中添加常量(比如调用intern方法),否则jvm不会自动添加常量到常量池。


Q: java实现了哪些常量池?
A:

  • 整型常量池、字符串常量池,(java中基本类型的包装类的大部分都实现了常量池技术,即Byte,Short,Integer,Long,Character,Boolean;
  • 两种浮点数类型的包装类Float,Double并没有实现常量池技术,
  • 数值类型的常量池不可以手动添加常量,程序启动时常量池中的常量就已经确定了,比如整型常量池中的常量范围:-128~127,
    (Byte,Short,Integer,Long,Character,Boolean)这5种包装类默认创建了数值[-128,127]的相应类型的缓存数据,但是超出此范围仍然会去创建新的对象。

Q: .class文件中的常量只有 我们定义的static final成员吗?
A: 不是,还有一堆和类定义相关的符号引用、字面常量等
这里深入剖析一下:
看一下 .class 开头部分的字节:


可以看到版本号之后就是常量池个数和常量池了。
这个文件中的常量会加载到静态常量池中。
有个class_info 符号引用。这是什么?
假设有个类A, 类A继承自父类B
那么文件里肯定得有个关系,来表示A继承自B, 那么就得有个内容来表示A和B是类,且有继承
于是文件里就会用class_info符号引用来代表A和B这2个类,并在文件里写上关系。

但是这个类得有个类名吧
那么在A.class里,肯定得有个字符串叫"A"吧
那么这个字符串就是一个utf8_info 字面常量, 并且A的class符号引用里会有指向这个字面常量的索引
像下面这样:

可以看一下其他的常量引用都有些什么:

然后class文件中如果想要表示某些关系比如接口啊父子类啊, 都会从这个池子里找引用或者字符串。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。