Java原始数据类型强化学习之常量池
Q:常量池的好处?
节省内存空间: 相同字符串常量都是同一个
可使用==做比较,节省运行时间: 常量间==做比较可直接比较地址,不用依次比较字符。
Q: 静态常量池 和动态常量池的区别:
前者一般存放class文件中可以看得到的常量
后者一般是运行中生成的常量, 经典的比如new String(“abcd”).intern() 之后,“abcd”就会被放到常量池中,这并非class文件中能看到的。
Q: 常量池放在哪?
根据之前看虚拟机那本书,说的是放在方法区。
但是听说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文件中如果想要表示某些关系比如接口啊父子类啊, 都会从这个池子里找引用或者字符串。
- 点赞
- 收藏
- 关注作者
评论(0)