>  기사  >  Java  >  자바 가상 머신의 클래스 파일 구조 소개

자바 가상 머신의 클래스 파일 구조 소개

零下一度
零下一度원래의
2017-06-25 10:41:041499검색

1. 서문

Java를 공부하는 친구들은 Java가 처음부터 "한 번 작성하면 어디서나 실행 가능"이라는 플랫폼 독립의 기치를 사용해 왔다는 것을 모두 알아야 합니다. 실제로 Java 플랫폼에는 독립성이 있습니다. 즉, 언어 독립성을 달성하려면 Java 시스템에서 클래스의 파일 구조나 바이트 코드가 매우 중요합니다. 실제로 Java에는 처음부터 두 가지 사양이 있습니다. 하나는 Java 언어 사양입니다. 다른 하나는 Java Virtual Machine 사양입니다. Java 언어 사양은 Java 언어와 관련된 제약 조건과 규칙만 규정하는 반면, Virtual Machine 사양은 진정한 크로스 플랫폼 관점에서 설계되었습니다.

아마 대부분의 프로그래머들은 자바 가상 머신이 자바 프로그램을 실행하는 것이 자연스럽고 당연하다고 생각하겠지만, 오늘날 상업 기관이나 오픈 소스 조직에서는 자바 언어 외에 자바 가상 머신을 기반으로 한 수많은 제품을 개발해 왔습니다. Clojure, Groovy, JRuby, Jython, Scale 등과 같은 언어를 실행합니다. Java 컴파일러를 사용하여 Java 코드를 바이트코드를 저장하는 클래스 파일로 컴파일할 수 있습니다. JRuby와 같은 다른 언어의 컴파일러를 사용하여 프로그램 코드를 클래스 파일로 컴파일할 수도 있습니다. Java 가상 머신은 플랫폼 독립적인 동일한 바이트코드를 로드하고 실행할 수 있기 때문입니다. 즉, 언어 플랫폼 독립성을 달성하기 위한 기반은 가상 머신과 바이트코드 저장 형식입니다. 가상 머신은 클래스 파일의 구조를 따르는 한 어떤 언어에서 왔는지 상관하지 않습니다. 자바 가상 머신.

2. 클래스 파일 인코딩 및 구성

1) 클래스 파일은 바이트(8bit) 기반의 바이트 스트림으로 구성되며, 이러한 바이트 스트림은 규정된 순서에 따라 엄격하게 배열되며 바이트 간 간격이 없습니다. 8바이트를 초과하는 데이터는 Big-Endian 순서로 저장됩니다. 즉, 상위 바이트는 하위 주소에 저장되고 하위 바이트는 상위 주소에 저장됩니다. PowerPC 아키텍처는 Big-Endian 저장 순서를 사용하는 반면 x86 시리즈 프로세서는 Little-Endian 저장 순서를 사용하기 때문에 크로스 플랫폼 클래스 파일의 핵심이므로 클래스 파일이 각 프로세서에 저장되도록 하려면 미드 프로세서 아키텍처에서는 가상 머신 사양이 이를 통합해야 합니다. 2) 클래스 파일 구조는 C 언어와 유사한 구조를 사용하여 데이터를 저장합니다. 데이터 항목에는 부호 없는 숫자와 테이블의 두 가지 주요 유형이 있습니다. 부호 없는 숫자는 숫자, 인덱스 참조 및 문자열 등을 표현하는 데 사용됩니다. u1, u2, u4, u8은 각각 1바이트, 2바이트, 4바이트, 8바이트의 부호 없는 숫자를 나타내고, 테이블은 여러 개의 부호 없는 숫자와 기타 테이블 구조의 합성입니다. 아마도 여기 있는 모든 사람들은 위의 부호 없는 숫자와 표가 무엇인지 명확하지 않을 수도 있지만 상관없습니다. 아래 예를 기다릴 때 예를 들어 설명하겠습니다.

위의 두 가지 사항을 명확히 한 후 클래스 파일에서 엄격한 순서로 정렬된 바이트 스트림에 포함된 특정 데이터를 살펴보겠습니다.

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

위 그림을 보면 한 가지 주의할 점이 있습니다. 예를 들어 위 그림에서 cp_info는 상수 풀에 상수 풀이 있다는 것을 나타내기 위해 사용됩니다. 여기서는 배열 형태로 표현되는데, 모든 상수 풀의 상수 길이가 같다고 착각하지 마세요 사실 이곳에서는 단지 설명의 편의를 위해 배열 방식을 사용하고 있습니다. int형 배열이 매번 사용되는 프로그래밍 언어와는 다릅니다. 각 int의 길이는 동일합니다.

3. 클래스 파일 구조 각 부분에 대한 자세한 소개

1) u4 매직은 매직넘버를 나타내며, 매직넘버는 4바이트를 차지합니다. 이는 실제로 파일 형식이 JPG 그림이나 AVI 동영상이 아닌 클래스 파일임을 의미합니다. Class 파일에 해당하는 매직 넘버는 0xCAFEBABE입니다.

2) u2 major_version은 Class 파일의 마이너 버전 번호를 나타내며, 이 버전 번호는 u2 유형의 부호 없는 숫자 표현입니다.
3) u2 major_version은 Class 파일의 메이저 버전 번호를 나타내며, 메이저 버전 번호는 u2 유형의 부호 없는 숫자 표현입니다.
major_version 및 major_version은 현재 가상 머신이 클래스 파일의 현재 버전을 허용하는지 여부를 나타내는 데 주로 사용됩니다. 다양한 버전의 Java 컴파일러로 컴파일된 클래스 파일의 버전이 다릅니다. 상위 버전 가상 머신은 하위 버전 컴파일러로 컴파일된 클래스 파일 구조를 지원합니다. 예를 들어 Java SE 6.0에 해당하는 가상 머신은 Java SE 5.0의 컴파일러에서 컴파일된 클래스 파일 구조를 지원하지만 그 반대의 경우는 지원하지 않습니다. 4) u2 Constant_pool_count는 상수 풀의 개수를 나타냅니다. 여기서는 상수 풀이 무엇인지에 초점을 맞춰야 합니다. Jvm 메모리 모델의 런타임 상수 풀과 혼동하지 마세요. 클래스 파일의 상수 풀은 주로 리터럴과 기호 참조를 저장합니다. 최종 상수의 값 또는 속성의 초기 값 등입니다. 기호 참조는 주로 클래스 및 인터페이스의 정규화된 이름, 필드의 이름 및 설명자, 메서드의 이름 및 설명자를 저장하며 여기에 있는 이름은 이해하기 쉬울 수 있습니다. 여러분, 디스크립터의 개념에 대해서는 아래에서 필드 테이블과 메소드 테이블에 대해 말씀드리겠습니다. 게다가 Jvm의 메모리 모델은 힙, 스택, 메소드 영역, 프로그램 카운터로 구성되어 있다는 사실은 다들 아시겠지만, 메소드 영역에는 런타임 상수 풀이라는 영역이 있습니다. 런타임 상수 풀에 저장되는 것들은 실제로는 컴파일러에 의해 생성됨 다양한 리터럴 및 기호 참조가 있지만 런타임 상수 풀은 동적입니다. 가장 대표적인 것은
String의 인턴 메서드입니다. 5) cp_info는 위에서 언급한 다양한 리터럴과 기호 참조가 포함된 상수 풀을 나타냅니다. 상수 풀에 배치된 데이터 항목에는 총 14개의 상수가 있으며, 각 상수는 테이블이며, 각 상수는 어떤 상수인지 나타내는 공통 부분 태그를 사용합니다.

상수 유형ValueCONSTANT_Class7CONSTANT_Methodref
CONSTANT_Class 7
CONSTANT_Fieldref 9
CONSTANT_Methodref 10
CONSTANT_InterfaceMethodref 11
CONSTANT_String 8
CONSTANT_Integer 3
CONSTANT_Float 4
CONSTANT_Long 5
CONSTANT_Double 6
CONSTANT_NameAndType 12
CONSTANT_Utf8 1
CONSTANT_MethodHandle 15
CONSTANT_MethodType 16
CONSTANT_InvokeDynamicCONSTANT_Fieldref 9

10🎜🎜🎜🎜CONSTANT_InterfaceMethodref🎜🎜11🎜🎜🎜 🎜CONSTANT_String🎜🎜8🎜🎜🎜🎜CONSTANT_Integer🎜🎜3🎜🎜🎜🎜CONSTANT_Float 🎜🎜4🎜🎜🎜🎜CONSTANT_Long🎜🎜5🎜🎜🎜🎜CONSTANT_Double🎜🎜6🎜🎜🎜 🎜CONSTANT_NameAndType🎜🎜12🎜🎜🎜🎜CONSTANT_Utf8🎜🎜1🎜🎜🎜🎜CONSTANT_MethodHandle 🎜🎜15🎜🎜🎜🎜CONSTANT_MethodType🎜🎜16🎜🎜🎜🎜CONSTANT_InvokeDynamic🎜🎜18🎜🎜🎜 🎜🎜🎜


6)u2 access_flags 表示类或者接口的访问信息,具体如下图所示:

Flag Name Value Interpretation
ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_FINAL 0x0010 Declared final; no subclasses allowed.
ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE 0x0200 Is an interface, not a class.
ACC_ABSTRACT 0x0400 Declared abstract; must not be instantiated.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation type.
ACC_ENUM 0x4000 Declared as an enum type.

7)u2 this_class 表示类的常量池索引,指向常量池中CONSTANT_Class的常量
8)u2 super_class 表示超类的索引,指向常量池中CONSTANT_Class的常量
9)u2 interface_counts 表示接口的数量
10)u2 interface[interface_counts]表示接口表,它里面每一项都指向常量池中CONSTANT_Class常量
11)u2 fields_count 表示类的实例变量和类变量的数量
12) field_info fields[fields_count]表示字段表的信息,其中字段表的结构如下图所示:

field_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

上图中access_flags表示字段的访问表示,比如字段是public、private、protect 等,name_index表示字段名称,指向常量池中类型是CONSTANT_UTF8的常量,descriptor_index表示字段的描述符,它也指向常量池中类型为 CONSTANT_UTF8的常量,attributes_count表示字段表中的属性表的数量,而属性表是则是一种用与描述字段,方法以及 类的属性的可扩展的结构,不同版本的Java虚拟机所支持的属性表的数量是不同的。
13) u2 methods_count表示方法表的数量
14)method_info 表示方法表,方法表的具体结构如下图所示:

method_info {
    u2             access_flags;
    u2             name_index;,
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

其中access_flags表示方法的访问表示,name_index表示名称的索引,descriptor_index表示方法的描述符,attributes_count以及attribute_info类似字段表中的属性表,只不过字段表和方法表中属性表中的属性是不同的,比如方法表中就有Code属性,表示方法的代码,而字段表中就没有Code属性。
15) attribute_count表示属性表的数量,说到属性表,我们需要明确以下几点:
属性表存在于Class文件结构的最后,字段表,方法表以及Code属性中,也就是说属性表中也可以存在属性表,属性表的长度是不固定的,不同的属性,属性表的长度是不同的

위 내용은 자바 가상 머신의 클래스 파일 구조 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.