5. CONSTANT_String_info
CONSTANT_String_info {
u1 tag;
u2 string_index;
}
字符串类型字面量
能够进入常量池:
- static final 修饰String 数据类型
- 其他出现的String字面量
代码:
package com.zuck.app2;
public class MyC1 {
//static final修饰的String类型会进入常量池
static final String str="123";
//虽然str2不会进入常量池(原因是它没被引用),但"456"是会进入常量池
String str2 = "456";
public void fun1(){
//"ok"也是字面量,也可进入常量池
System.out.println("ok");
}
{
//实例块,"yyy"能进入常量池
System.out.println("yyy");
}
static {
//静态块也能进入常量池,但常量池中存的是"abcdef"(优化)
String str3 = "abc" + "def";
//"xxx567",整型被优化成String
String str4 = "xxx" + 567;
}
}
6. CONSTANT_Integer_info
CONSTANT_Integer_info {
u1 tag;
u4 bytes;
}
整型字面量
什么能进?
- static final修饰 byte,char,short,boolean,int数据类型的
- 非static final修饰的,在-32768到32767范围内的,直接进入字节码指令内部。否则才进入CONSTANT_Integer_info常量池
举例:
public class MyC2 {
//以下字面量均会进入 CONSTANT_Integer_info
static final int a = 10;
static final boolean b1 = true;
static final boolean b2 = false;
static final char c1 = 'a';
static final byte by1 = 20;
static final short s1 = 30;
public void fun2(){
//范围如果是在short范围内不会进入常量池,会直接进入字节码里(为了优化)
int a = 50;
//50000却能进入常量池
//int a = 50000;
}
static {
//300不会进入常量池
int b = 100 + 200;
}
}
300不会进入常量池,会进入到这里
7. CONSTANT_Float_info
CONSTANT_Float_info {
u1 tag;
u4 bytes;
}
浮点型字面量
什么能进?
- static final 修饰 float
- 其他使用的
举例:
public class MyC1 {
static final float f1=15.5f;
//只要是字面量(25.5),就得进常量池,
float f2=25.5f;
public void fun1(){
//局部变量也是要进常量池
float f3=35.5f;
}
static{
//静态块也要进常量池
float f4=45.5f;
}
public void fun4(){
fun5(55.5f);
}
//只要是字面量,都能进取,不管你是不是函数的参数
public void fun5(float f){
}
}
一个面试题:
public class MyC2 {
public MyC2(){
System.out.println(100);
}
static {
System.out.println(200);
}
{
System.out.println(300);
}
}
构造方法、静态代码块、实例块,三者谁先执行?
8.CONSTANT_Long_info
CONSTANT_Long_info {
u1 tag;
u4 high_bytes;
u4 low_bytes;
}
public class MyC3 {
//进入常量池
static final long l1=10;
//进入常量池
static long l2=20;
//进入常量池
public MyC3() {
long l3=30;
}
}
9.CONSTANT_Double_info
CONSTANT_Double_info {
u1 tag;
u4 high_bytes;
u4 low_bytes;
}
双精度浮点型字面量
high_bytes 高32位区
low_bytes 低32位区
举例:
public class MyC4 {
static final double d1 = 15.6;
static double d2 = 25.6;
double d3=35.6;
public MyC4() {
double d4 = 45.6;
}
}
以上均能进入常量池
字面量和Fieldref_info出现的规则
- 字面量:数据类型是String、基本数据类型(不包含包装类)
- 引用类型(非字面量,含基本数据类型的包装类)
- static final修饰的字面量在本类和其他类里面都会以字面量类型的常量出现
- 非static final修饰的字面量在本类以字面量类型的常量出现和Fieldref_info类型的常量出现
- 非static final修饰的字面量在其他类以Fieldref_info的类型的常量出现
- 引用类型在本类和其他类里面都会出现 Fieldref_info
- static final修饰的字面量不会出现Fieldref_info
- static final修饰的基本数据类型包装类会同时出现Fieldref_info和包装类的字面量常量类型
10.CONSTANT_NameAndType_info
CONSTANT_NameAndType_info {
u1 tag;
u2 name_index;
u2 descriptor_index;
}
11. CONSTANT_Utf8_info
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
UTF-8编码字符串
JVM需要用到的字符串,都会存起来
以下三个,是为了支持动态类型语言,比如lambda表达式
12. CONSTANT_MethodHandle_info
CONSTANT_MethodHandle_info {
u1 tag;
u1 reference_kind;
u2 reference_index;
}
13. CONSTANT_MethodType_info
CONSTANT_MethodType_info {
u1 tag;
u2 descriptor_index;
}
14. CONSTANT_InvokeDynamic_info
CONSTANT_InvokeDynamic_info {
u1 tag;
u2 bootstrap_method_attr_index;
u2 name_and_type_index;
}