按照《java虚拟机规范SE7》章节顺序整理的笔记。

目录:

  1. ClassFile格式(注:也就是class文件的总结构)
  2. 描述符和签名
  3. 常量池
  4. 字段
  5. 方法
  6. 属性
  7. Java虚拟机代码约束
  8. Class文件校验

第四章:class文件格式

这一章详细的介绍了class文件的格式,包括class文件的格式,class文件具体的内容。这些内容均可以通过自己编写一个简单的类,并使用javap反编译来对照着阅读。


<1>. ClassFile格式

这表示class文件的总结构,也就是说:满足虚拟机规范的class文件的构成。
值得注意的是:

  • 其中u1,u2,u4分别代表这个项打大小为 1,2,4个字节。
  • 其中的cp_info, field_info, method_info, attribute_info表示这个表中项的结构,同时也说明这个项的大小暂时是不确定的。
  • 结构中一共有五个表:常量池表,接口表,字段表,方法表,属性表
    而其中只有常量池表是从1开始索引,而其他表均从0开始索引,所以常量池计数器比实际常量的大小多1。
  • 需要重点提出的是,每个class仅仅是针对当前类,或者他的直接父类,如:
    1.字段表仅仅包含当前类或接口声名的字段,并不包含父类或父接口。
    2.方法表仅仅包含当前类或接口声明的方法,并不包含父类或父接口。
ClassFile { u4 magic;   //魔数,唯一的作用是标志当前class是否符合虚拟机规范,//唯一的值为:0xCOFEBABE(咖啡宝宝?)u2 minor_version;   //副版本号u2 major_version;   //主版本号//主版本号和副版本号结合起来,作用是表示当前的class是否被某个版本的java虚拟机支持。//各个版本的虚拟机都有自己支持的主副版本号范围。u2 constant_pool_count;   //常量池计数器,值为后面常量池表成员数加1.cp_info constant_pool[constant_pool_count-1];   //常量池表,//每一项都是cp_info结构,索引从1到constant_pool_count-1。u2 access_flags;   //访问标志,标志类或接口的访问权限及基础属性(值见下表)。u2 this_class;    //类索引,表示当前文件的类或接口,值得注意,类并非一定与文件名相同,如:内部类。u2 super_class;   //直接父类//如果值为0:表示没有父类,而java中没有父类的只有java.lang.Object//如果不是0:表示这个一个类或接口,他的值必须是常量池中的CONSTANT_Class_info的值u2 interfaces_count;   //接口计数器,大小为当前类直接父接口数量。u2 interfaces[interfaces_count];   //接口表//每一项的值都是常量池中的CONSTANT_Class_info类型的值。//索引从0开始。u2 fields_count;   //字段计数器 ,大小为当前类或接口所定义的字段。field_info fields[fields_count];   //字段表//每一项都是field_info结构。索引从0开始。u2 methods_count;  //方法计数器,大小为当前类或接口所定义的方法。method_info methods[methods_count];   //方法表//每一项都是method_info结构。索引从0开始。u2 attributes_count;  //属性计数器,大小为class文件中的属性数量。   attribute_info attributes[attributes_count];   //属性表每一项都是attribute_info结构。索引从0开始。
}

访问标志一览表 (access_flags):

标记名 含义
ACC_PUBLIC 0x0001 可以被包的类外访问
ACC_FINAL 0x0010 不允许有子类
ACC_SUPER 0x0020 当用到invokespecial指令时,需要特殊处理的父类方法
ACC_INTERFACE 0x0200 标识定义的是接口而不是类
ACC_ABSTRACT 0x0400 不能被实例化
ACC_SYNTHETIC 0x1000 标识并非Java源码生成的代码
ACC_ANNOTATION 0x2000 标识注解类型
ACC_ENUM 0x4000 标识枚举类型

<2>. 描述符和签名

描述符:一个描述字段或方法的类型的字符串。
可分为:

  • 字段描述符
  • 方法描述符

a.字段描述符:描述了字段的类型。

  1. 描述原始类型
字符 类型 含义
B byte 有符号字节型数
C char Unicode字符,UTF-16编码
D double 双精度浮点数
F float 单精度浮点数
I int 整型数
J long 长整数
S short 有符号短整数
Z boolean 布尔值 true/false
L Classname; reference 一个名为的实例
[ reference 一个一维数组
  1. 描述对象
    格式:L+Classname
    注:这里的Classname是类的全限定名,如Object类,Ljava.lang.Object

  2. 描述数组
    格式:[ + ComponentType
    例如:[ I , [[java.lang.Object

b. 方法描述符:描述了方法的参数类型,参数大小,和返回类型。
格式:( 使用字段描述符描述的0或n个参数 ) 返回类型同样使用字段描述符表示
例如:方法 int method(int a,Object b) 描述为 ( I [java.lang.Object; ) I ;

注意:对于实例方法中的this参数,并不显示的写在方法描述符中,它是在java虚拟机调用方法的时候隐式传递。

签名:是用于描述字段、方法和类型定义中的泛型信息的字符串。
签名是用于给Java语言使用的描述信息编码,不在Java虚拟机系统使用的类型中。

  1. 类签名,作用是把Class申明的类型信息编译成对应的签名信息。
  2. 字段类型签名,作用是将字段、参数或局部变量的类型编译成对应的签名信息。
  3. 方法签名,作用是将方法中所有的形式参数的类型编译成相应的签名信息(或将它们参数化)。

<3>. 常量池

常量池中每一项都是一个cp_info结构,而cp_info的结构如下:

cp_info { u1 tag; u1 info[];   //这个值的大小由tag标志决定。
}

例如CONSTANT_Class_info 表示为:

CONSTANT_Class_info{u1 tag;u2 name_index;
}

tag标签一共有14种,如下表:

常量类型
CONSTANT_Class_info 7
CONSTANT_Fieldref_info 9
CONSTANT_Methodref_info 10
CONSTANT_InterfaceMethodref_info 11
CONSTANT_String_info 8
CONSTANT_Integer_info 3
CONSTANT_Float_info 4
CONSTANT_Long_info 5
CONSTANT_Double_info 6
CONSTANT_NameAndType_info 12
CONSTANT_Utf8_info 1
CONSTANT_MethodHandle_info 15
CONSTANT_MethodType_info 16
CONSTANT_InvokeDynamic_info 18

类 ——CONSTANT_Class_info 格式:

CONSTANT_Class_info{u1 tag;  //值为 7u2 name_index;  //name_index项的值,必须是对常量池的一个有效索引。//常量池在该索引处的项必须是CONSTANT_Utf8_info(§4.4.7)结构,//代表一个有效的类或接口二进制名称的内部形式。
}

字段,方法,接口方法——CONSTANT_Fieldref_info, CONSTANT_Methodref_info和CONSTANT_InterfaceMethodref_info的格式相同:

CONSTANT_Fieldref_info { u1 tag;  //值为 9u2 class_index;  //class_index项的值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Class_info结构,既可以是类也可以是接口。u2 name_and_type_index;  //name_and_type_index项的值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_NameAndType_info结构,必须是字段描述符。
}
CONSTANT_Methodref_info { u1 tag;  //值为 10u2 class_index;   //class_index项的值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Class_info结构,且必须是类(不能是接口)。u2 name_and_type_index; //name_and_type_index项的值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_NameAndType_info结构,必须是方法描述符
}
CONSTANT_InterfaceMethodref_info { u1 tag;  //值为 11u2 class_index; //class_index项的值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Class_info结构,且必须是接口(不能是类)。u2 name_and_type_index;  //name_and_type_index项的值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_NameAndType_info结构,必须是方法描述符
}

*字符串——CONSTANT_String_info 格式:

CONSTANT_String_info {u1 tag;  //值为 8u2 string_index;   //必须是对常量池的有效索引,索引处的项必须是CONSTANT_Utf8_info
}

数值常量——CONSTANT_Integer_info,CONSTANT_Float_info 格式:

CONSTANT_Integer_info { u1 tag; //值为 3 u4 bytes; //int类型常量值
}
CONSTANT_Float_info { u1 tag;  //值为 4u4 bytes;  //float类型常量值
}

float类型的值按照下面方法表示,bytes项的值首先被转换成一个int常量的bits:

  • 如果bits值为0x7f800000,表示float值为正无穷。
  • 如果bits值为0xff800000,表示float值为负无穷。
  • 如果bits值在范围0x7f800001到0x7fffffff或者0xff800001到0xffffffff内,表示float值为NaN。
  • 在其它情况下,设s、e、m,它们值根据bits和如下公式计算:
int s =((bits >> 31) == 0) ? 1 : -1;
int e =((bits >> 23) & 0xff);
int m =(e == 0) ? bits & 0x7fffff) << 1 : (bits & 0x7fffff) | 0x800000;

则float的浮点值为数值表达式s·m·2^(e–150)的计算结果。

数值常量——CONSTANT_Long_info和CONSTANT_Double_info 格式:

在Class文件的常量池中,所有的8字节的常量都占两个表成员(项)的空间。如果一个CONSTANT_Long_info或CONSTANT_Double_info结构的项在常量池中的索引为n,则常量池中下一个有效的项的索引为n+2,此时常量池中索引为n+1的项有效但必须被认为不可用。

CONSTANT_Long_info { u1 tag;   //值为 5u4 high_bytes; u4 low_bytes;
}
CONSTANT_Double_info { u1 tag;   //值为6u4 high_bytes; u4 low_bytes;
}

Long:high_bytes和low_bytes项用于共同表示long型常量,构造形式为
((long) high_bytes << 32) + low_bytes
也就是将高位在前,地位在后

Double:与上一个Float类似,首先被转换成一个long常量的bits:

  • 如果bits值为0x7ff0000000000000L,表示double值为正无穷。
  • 如果bits值为0xfff0000000000000L,表示double值为负无穷。
  • 如果bits值在范围0x7ff0000000000001L到 0x7fffffffffffffffL或者0xfff0000000000001L到 0xffffffffffffffffL内,表示double值为NaN。
  • 在其它情况下,设s、e、m,它们的值根据bits和如下公式计算:
int s =((bits >> 63) == 0) ? 1 : -1;
int e =(int)((bits >> 52) & 0x7ffL);
long m =(e == 0) ? (bits & 0xfffffffffffffL) << 1 : (bits & 0xfffffffffffffL) | 0x10000000000000L;

则double的浮点值为数学表达式s·m·2e – 1075的计算结果。

表示字段或方法——CONSTANT_NameAndType_info 格式:

CONSTANT_NameAndType_info { u1 tag;   //值为 12u2 name_index;  //必须是对常量池的有效索引CONSTANT_Utf8_info,这个结构要么表示特殊的方法名<init>,要么表示一个有效的字段或方法的非限定名。u2 descriptor_index; //索引处的项必须是CONSTANT_Utf8_info,这个结构表示一个有效的字段描述符或方法描述符。
}

表示字符串常量——CONSTANT_Utf8_info 格式 :

CONSTANT_Utf8_info { u1 tag;   //值为 1u2 length;   //指明了bytes[]数组的长度u1 bytes[length];  //bytes[]是表示字符串值的byte数组,bytes[]数组中每个成员的byte值都不会是0,也不在0xf0至0xff范围内。
}

方法句柄——CONSTANT_MethodHandle_info 格式:

CONSTANT_MethodHandle_info {u1 tag;  //值为 15u1 reference_kind;   //值必须在1-9之间,根据这个值的不同,将造成下面项的不同。u2 reference_index;
}

reference的取值:

  • 如果reference_kind项的值为1(REF_getField)、2(REF_getStatic)、3(REF_putField)或4(REF_putStatic),那么常量池在reference_index索引处的项必须是CONSTANT_Fieldref_info(§4.4.2)结构,表示由一个字段创建的方法句柄。
  • 如果reference_kind项的值是5(REF_invokeVirtual)、6(REF_invokeStatic)、7(REF_invokeSpecial)或8(REF_newInvokeSpecial),那么常量池在reference_index索引处的项必须是CONSTANT_Methodref_info(§4.4.2)结构,表示由类的方法或构造函数创建的方法句柄。
  • 如果reference_kind项的值是9(REF_invokeInterface),那么常量池在reference_index索引处的项必须是CONSTANT_InterfaceMethodref_info(§4.4.2)结构,表示由接口方法创建的方法句柄。
  • 如果reference_kind项的值是5(REF_invokeVirtual)、6(REF_invokeStatic)、7(REF_invokeSpecial)或9(REF_invokeInterface),那么方法句柄对应的方法不能为实例初始化()方法或类初始化方法()。
  • 如果reference_kind项的值是8(REF_newInvokeSpecial),那么方法句柄对应的方法必须为实例初始化()方法。

表示invokedynamic指令所使用到的引导方法——CONSTANT_InvokeDynamic_info 格式:

CONSTANT_InvokeDynamic_info { u1 tag;   //值为 18u2 bootstrap_method_attr_index; u2 name_and_type_index;
}

<4>. 字段

字段每一项都是一个field_info结构:

field_info { u2 access_flags;   //字段的访问标志,包括访问限制,基础属性u2 name_index;   //必须是对常量池的一个有效索引。常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示一个有效的字段的非全限定名。u2 descriptor_index;   //索引处的项必须是CONSTANT_Utf8_info结构,表示一个有效的字段的描述符u2 attributes_count;   //字段的属性计数器attribute_info attributes[attributes_count];  //attributes表的每一个成员的值必须是attribute结构,一个字段可以有任意个关联属性。
}

字段访问标志一览表:

标记名 说明
ACC_PUBLIC 0x0001 public,表示字段可以从任何包访问。
ACC_PRIVATE 0x0002 private,表示字段仅能该类自身调用。
ACC_PROTECTED 0x0004 protected,表示字段可以被子类调用。
ACC_STATIC 0x0008 static,表示静态字段。
ACC_FINAL 0x0010 final,表示字段定义后值无法修改(JLS §17.5)。
ACC_VOLATILE 0x0040 volatile,表示字段是易变的。
ACC_TRANSIENT 0x0080 transient,表示字段不会被序列化。
ACC_SYNTHETIC 0x1000 表示字段由编译器自动产生。
ACC_ENUM 0x4000 enum,表示字段为枚举类型。

<5>. 方法

方法的每一项都是一个method_info结构:

method_info { u2 access_flags;  //方法访问标志u2 name_index;  //常量池在该索引处的项必须是CONSTANT_Utf8_info结构,它要么表示初始化方法的名字(<init>或<clinit>),要么表示一个方法的有效的非全限定名。u2 descriptor_index;   //。常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示一个有效的方法的描述符 注意:本规范在未来的某个版本中可能会要求当access_flags项的ACC_VARARGS标志被设置时,方法描述符中的最后一个参数必须是数组类型。u2 attributes_count;   //方法属性计数器attribute_info attributes[attributes_count]; //attributes表的每一个成员的值必须是attribute结构,一个方法可以有任意个与之相关的属性。
}

方法访问标志一览表:

标记名 说明
ACC_PUBLIC 0x0001 public,方法可以从包外访问
ACC_PRIVATE 0x0002 private,方法只能本类中访问
ACC_PROTECTED 0x0004 protected,方法在自身和子类可以访问
ACC_STATIC 0x0008 static,静态方法
ACC_FINAL 0x0010 final,方法不能被重写(覆盖)
ACC_SYNCHRONIZED 0x0020 synchronized,方法由管程同步
ACC_BRIDGE 0x0040 bridge,方法由编译器产生
ACC_VARARGS 0x0080 表示方法带有变长参数
ACC_NATIVE 0x0100 native,方法引用非java语言的本地方法
ACC_ABSTRACT 0x0400 abstract,方法没有具体实现
ACC_STRICT 0x0800 strictfp,方法使用FP-strict浮点格式
ACC_SYNTHETIC 0x1000 方法在源文件中不出现,由编译器产生

方法属性表的值可以有:

  • Code
  • Exceptions
  • Synthetic
  • Signature
  • Deprecated
  • untimeVisibleAnnotations
  • RuntimeInvisibleAnnotations
  • RuntimeVisibleParameterAnnotations
  • RuntimeInvisibleParameterAnnotations
  • AnnotationDefault

<6>. 属性

属性的每一项都是attribute_info结构:

attribute_info { u2 attribute_name_index;   //是常量池中的CONSTANT_Utf8_info索引。u4 attribute_length;  u1 info[attribute_length];
}

ConstantValue属性:
位于field_info结构的属性表中,表示一个常量字段的值,在一个field_info结构的属性表中最多只能有一个ConstantValue属性。
格式:

ConstantValue_attribute { u2 attribute_name_index; u4 attribute_length; u2 constantvalue_index;
}

Code属性:
位于method_info结构的属性表,一个Code属性只为唯一一个方法、实例类初始化方法或类初始化方法保存Java虚拟机指令及相关辅助信息。
如果方法被声明为native或者abstract类型,那么对应的method_info结构不能有明确的Code属性。
格式:

Code_attribute { u2 attribute_name_index; u4 attribute_length; u2 max_stack; u2 max_locals; u4 code_length; u1 code[code_length]; u2 exception_table_length;{ u2 start_pc; u2 end_pc; u2 handler_pc; u2 catch_type; } exception_table[exception_table_length]; u2 attributes_count; attribute_info attributes[attributes_count];
}

StackMapTable属性:
位于Code属性的属性表中,这个属性会在虚拟机类加载的类型阶段被使用。
格式:

StackMapTable_attribute { u2 attribute_name_index; u4 attribute_length; u2 number_of_entries; stack_map_frame entries[number_of_entries];
}

Exceptions属性:
它位于method_info结构的属性表中,指出了一个方法需要检查的可能抛出的异常。
格式:

Exceptions_attribute { u2 attribute_name_index; u4 attribute_length; u2 number_of_exceptions; u2 exception_index_table[number_of_exceptions];
}

InnerClasses属性:
位于ClassFile结构的属性表,支持内部类和内部接口而引入。
格式:

InnerClasses_attribute { u2 attribute_name_index; u4 attribute_length; u2 number_of_classes;{ u2 inner_class_info_index; u2 outer_class_info_index; u2 inner_name_index; u2 inner_class_access_flags;} classes[number_of_classes];
}

EnclosingMethod属性:
位于ClassFile结构的属性表,且仅当Class为局部类或者匿名类时,才能具有EnclosingMethod属性,一个类中只能有一个。
格式:

EnclosingMethod_attribute { u2 attribute_name_index; u4 attribute_length; u2 class_index u2 method_index;
}

Synthetic属性:
位于ClassFile中的属性表,如果一个类成员没有在源文件中出现,则必须标记带有Synthetic属性,或者设置ACC_SYNTHETIC标志。
格式:

Synthetic_attribute { u2 attribute_name_index; u4 attribute_length;
}

Signature属性:
位于ClassFile,field_info或method_info结构的属性表中,任何类、接口、初始化方法或成员的泛型签名如果包含了类型变量或参数化类型,则Signature属性会为它记录泛型签名信息。
格式:

Signature_attribute { u2 attribute_name_index; u4 attribute_length; u2 signature_index;
}

SourceFile属性:
位于ClassFile结构的属性表,一个ClassFile结构中的属性表最多只能包含一个SourceFile属性。
格式:

 SourceFile_attribute { u2 attribute_name_index; u4 attribute_length; u2 sourcefile_index; }

SourceDebugExtension 属性:
位于ClassFile(§4.1)结构属性表,最多只能包含一个SourceDebugExtension属性。
格式:

SourceDebugExtension_attribute { u2 attribute_name_index; u4 attribute_length; u1 debug_extension[attribute_length];
}

LineNumberTable属性:
位于Code结构的属性表,用于确定源文件中行号表示的内容在Java虚拟机的code[]数组中对应的部分。
格式:

LineNumberTable_attribute { u2 attribute_name_index; u4 attribute_length; u2 line_number_table_length; { u2 start_pc; u2 line_number; } line_number_table[line_number_table_length];
}

LocalVariableTable属性:
位于Code属性的属性表中,用于确定方法在执行过程中局部变量的信息。
格式:

LocalVariableTable_attribute { u2 attribute_name_index; u4 attribute_length; u2 local_variable_table_length; { u2 start_pc; u2 length; u2 name_index; u2 descriptor_index;u2 index; } local_variable_table[local_variable_table_length];
}

LocalVariableTypeTable属性:
位于Code的属性表,用于给调试器确定方法在执行中局部变量的信息。
格式:

LocalVariableTypeTable_attribute { u2 attribute_name_index; u4 attribute_length; u2 local_variable_type_table_length;{ u2 start_pc; u2 length; u2 name_index; u2 signature_index; u2 index; }local_variable_type_table[local_variable_type_table_length];
}

Deprecated属性:
位于ClassFile, field_info 或 method_info结构的属性表中,标记了此属性,则说明它将会在后续某个版本中被取代。
格式:

Deprecated_attribute { u2 attribute_name_index; u4 attribute_length;
}

RuntimeVisibleAnnotations属性:
位于ClassFile, field_info或method_info结构的属性表中,用于保存Java语言中的类、字段或方法的运行时的可见注解。
格式:

RuntimeVisibleAnnotations_attribute { u2 attribute_name_index; u4 attribute_length; u2 num_annotations; annotation annotations[num_annotations];
}

RuntimeInvisibleAnnotations 属性:
位于ClassFile, field_info或method_info结构的属性表中,用于保存Java语言中的类、字段或方法的运行时的非可见注解。
格式:

RuntimeInvisibleAnnotations_attribute { u2 attribute_name_index; u4 attribute_length; u2 num_annotations; annotation annotations[num_annotations];
}

RuntimeVisibleParameterAnnotations属性:
位于method_info结构的属性表中 ,用于保存对应方法的参数的所有运行时可见Java语言注解
格式:

RuntimeVisibleParameterAnnotations_attribute { u2 attribute_name_index; u4 attribute_length; u1 num_parameters; { u2 num_annotations; annotation annotations[num_annotations]; } parameter_annotations[num_parameters];
}

RuntimeInvisibleParameterAnnotations属性:
位于method_info结构的属性表中,用于保存对应方法的参数的所有运行时非可见的Java语言注解。
格式:

RuntimeInvisibleParameterAnnotations_attribute { u2 attribute_name_index; u4 attribute_length; u1 num_parameters; { u2 num_annotations; annotation annotations[num_annotations]; } parameter_annotations[num_parameters];
}

AnnotationDefault属性:
位于某些特殊的method_info结构的属性表中,这些结构表示注解类型的元素,用于保存method_info结构表示的元素的默认值。
格式:

AnnotationDefault_attribute { u2 attribute_name_index; u4 attribute_length; element_value default_value;
}

BootstrapMethods属性:
位于ClassFile结构的属性表中,用于保存invokedynamic指令引用的引导方法限定符。
格式:

BootstrapMethods_attribute { u2 attribute_name_index; u4 attribute_length; u2 num_bootstrap_methods; {  u2 bootstrap_method_ref; u2 num_bootstrap_arguments; u2 bootstrap_arguments[num_bootstrap_arguments]; } bootstrap_methods[num_bootstrap_methods];
}

<7>. Java虚拟机代码约束

这里使用了很多对java虚拟机的约束,由于内容过多,且对只是为了解一些java虚拟机情况的我来说并不需要深入理解,便不摘录了。


至此,对于javac编译的class文件也有了深入的理解,对java虚拟机内部结构也有了认识。后面的内容主要就是:Java虚拟机如何加载class文件。

《java虚拟机规范SE7》整理——第四章:Class文件格式相关推荐

  1. 《java虚拟机规范SE7》整理——第三章:为Java虚拟机编译

    按照<java虚拟机规范SE7>章节顺序整理的笔记. 目录: 常量.局部变量的使用和控制结构 算术运算 访问运行时常量池 接收参数 方法调用 使用类实例 数组 编译switch语句 抛出异 ...

  2. 《java虚拟机规范SE7》整理——第五章:加载,链接与初始化

    按照<java虚拟机规范SE7>章节顺序整理的笔记. 目录: 运行时常量池 虚拟机启动 创建和加载 链接 初始化 绑定本地方法实现 Java虚拟机退出 第四章:加载,链接与初始化 java ...

  3. 《java虚拟机规范SE7》整理——第二章:Java虚拟机结构

    按照<java虚拟机规范SE7>章节顺序整理的笔记. 第二章:java虚拟机的结构 目录: 数据类型 运行时数据区 栈帧 浮点算法 字节码指令集 一. 数据类型 虚拟机可以操作的类型可以分 ...

  4. 深入了解java虚拟机(JVM) 第四章 对象的创建

    一.对象的创建过程 对象的创建过程大致可以分为六步,其中对象的分配尤为重要: 二.对象分配内存 一般来说对象分配内存有两种方式: 第一种是指针碰撞,这是一种比较理想的方式:如果Java堆是绝对规整的: ...

  5. 《Java虚拟机规范》阅读(三):Class文件格式

    每一个Class都对应着唯一的一个类或借口的定义信息.这里,我们称为"Class文件格式"只是通俗的将任意一个符合有效的类或借口的格式这么称呼,但是它并不一定是以磁盘文件的形式存在 ...

  6. java 反射驻足类型_《Java虚拟机规范》阅读(三):Class文件格式

    每一个Class都对应着唯一的一个类或借口的定义信息.这里,我们称为"Class文件格式"只是通俗的将任意一个符合有效的类或借口的格式这么称呼,但是它并不一定是以磁盘文件的形式存在 ...

  7. java虚拟机规范这本书怎么样_JVM规范系列开篇:为什么要读JVM规范?

    博主个人独立站点开通啦!欢迎点击访问:https://shuyi.tech 许多人知道类加载机制.JVM内存模型,但他们可能不知道什么是<Java虚拟机规范>.对于Java开发来说,< ...

  8. 《深入理解JAVA虚拟机》详细解读(第二章 ):JAVA内存区域与内存溢出异常

    目录 一.JAVA内存区域与内存溢出异常 1. 概述 2. 运行时数据区域 2.1 程序计数器 2.2 Java虚拟机栈 2.3本地方法栈 2.4 堆 2.5 方法区 2.6 运行时常量池 2.7直接 ...

  9. java虚拟机规范 51cto_java虚拟机

    最近学习java虚拟机做了一些整理,会陆续发完. Java虚拟机 一.概念:当我们谈到java虚拟机的时候,有可能指下面3个方面: 1):抽象java虚拟机的规范. 2):一个java虚拟机具体的实现 ...

最新文章

  1. OpenShift — 架构设计
  2. Android TextView内容过长加省略号,点击显示全部内容
  3. 文件路径最好使用正斜杠,使用反斜杠可能在unix系统中访问不到文件
  4. struts2原理分析之反射技术动态获取属性
  5. .NET Core + Kubernetes:Volume
  6. 通过Source insight查看内核源码
  7. 编译安装MongoDB以及安装PHP的mongodb扩展
  8. Yii2.0数据格式器
  9. 批处理学习笔记6 - 重定向符和
  10. ubuntu linux 系统搭建我的世界基岩版 私服我的世界服务器
  11. js 正则表达式总结
  12. 源码文件编码问题,导致编译的程序运行错误
  13. max std value 宏_常用宏定义
  14. php实现给excel(xlsx)文件添加背景图水印
  15. 计算机毕业设计之java+ssm乐轩公司订餐系统
  16. 神经网络与深度学习第三周-Planar data classification with one hidden layer
  17. 【python第3课】顺序、循环、分支
  18. html怎么移动按钮位置,CSS Nav按钮向左下方移动(CSS Nav buttons move bottom left)
  19. 镭速软件如何使用文件同步功能?
  20. 迷你MVVM框架 avalonjs 入门教程

热门文章

  1. vue项目使用yxg-xlsx-style组件将表格数据导出带有样式的excel文件
  2. 利用vpython的单摆运动模拟
  3. UEFI 之 LoadImage探索
  4. wifi共享精灵 强大的网络伴侣
  5. 微服务时代下崛起的 TestOps 工程师
  6. 今天是个值得纪念的日子
  7. 删除战神引擎手游服务端里面自带的病毒文件教程
  8. 微信小程序之图片、音频、视频上传(附前后端代码示例)
  9. 基于STM32F103入门4——串口通信
  10. Amesim学习——热传导基础案例:金和铝的导热性比较