电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

Class文件详解 (1)


发布日期:2018/9/20
 

我们都知道Java编译器负责将java文件编译成class文件class文件存储的是java字节码java文件无关(只要你愿意写一个编译器也可以将别的语言写的源代码编译成class文件)本文准备详细解剖class文件的内部结构并且把class文件结构读取并显示出来

Class文件的格式由JVM规范规定一共有以下部分

magic number必须是xCAFEBABE用于快速识别是否是一个class文件

version包括major和minor如果版本号超过了JVM的识别范围JVM将拒绝执行

constant pool常量池存放所有用到的常量

access flag定义类的访问权限

this class和super class指示如何找到this class和super class

interfaces存放所有interfaces

fields存放所有fields

methods存放所有methods

attributes存放所有attributes

先写一个Testjava

package exampletest;

public final class TestClass {

public int id = ;

public void test() {}

}

然后编译放在C:\example\test\Testclass

我们用Java来读取和分析classClassAnalyzer的功能便是读取Testclass分析结构然后显示出来

package classfileformat;

import javaio*;

public class ClassAnalyzer {

public static void main(String[] args) {

DataInputStream input = null;

try {

input = new DataInputStream(new BufferedInputStream(new FileInputStream(

C:\\example\\test\\TestClassclass

)));

analyze(input);

}

catch(Exception e) {

Systemoutprintln(Analyze failed!);

}

finally {

try { inputclose(); } catch(Exception e) {}

}

}

public static void analyze(DataInputStream input) throws IOException {

// read magic number:

int magic = inputreadInt();

if(magic==xCAFEBABE)

Systemoutprintln(magic number = xCAFEBABE);

else

throw new RuntimeException(Invalid magic number!);

// read minor version and major version:

short minor_ver = inputreadShort();

short major_ver = inputreadShort();

Systemoutprintln(Version = + major_ver + + minor_ver);

// read constant pool:

short const_pool_count = inputreadShort();

Systemoutprintln(constant pool size = + const_pool_count);

// read each constant:

for(int i=; ianalyzeConstant(input, i);

}

}

public static void analyzeConstant(DataInputStream input, int index) throws IOException {

byte flag = input.readByte();

// for read:

byte n8;

short n16;

int n32;

long n64;

float f;

double d;

byte[] buffer;

System.out.println("\nconst index = " + index + ", flag = " + (int)flag);

switch(flag) {

case 1: // utf-8 string

System.out.println(" const type = Utf8");

n16 = input.readShort();

System.out.println(" length = " + n16);

buffer = new byte[n16];

input.readFully(buffer);

System.out.println("value = " + new String(buffer));

break;

case 3: // integer

System.out.println(" const type = Integer");

n32 = input.readInt();

System.out.println("value = " + n32);

break;

case 4: // float

System.out.println(" const type = Float");

f = input.readFloat();

System.out.println("value = " + f);

break;

case 5: // long

System.out.println(" const type = Long");

n64 = input.readLong();

System.out.println("value = " + n64);

break;

case 6: // double

System.out.println(" const type = Double");

d = input.readDouble();

System.out.println("value = " + d);

break;

case 7: // class or interface reference

System.out.println(" const type = Class");

n16 = input.readShort();

System.out.println("index = " + n16 + " (where to find the class name)");

break;

case 8: // string

System.out.println(" const type = String");

n16 = input.readShort();

System.out.println("index = " + n16);

break;

case 9: // field reference

System.out.println(" const type = Fieldref");

n16 = input.readShort();

System.out.println("class index = " + n16 + " (where to find the class)");

n16 = input.readShort();

System.out.println("nameAndType = " + n16 + " (where to find the NameAndType)");

break;

case 10: // method reference

System.out.println(" const type = Methodref");

n16 = input.readShort();

System.out.println("class index = " + n16 + " (where to find the class)");

n16 = input.readShort();

System.out.println("nameAndType = " + n16 + " (where to find the NameAndType)");

break;

case 11: // interface method reference

System.out.println(" const type = InterfaceMethodref");

n16 = input.readShort();

System.out.println("class index = " + n16 + " (where to find the interface)");

n16 = input.readShort();

System.out.println("nameAndType = " + n16 + " (where to find the NameAndType)");

break;

case 12: // name and type reference

System.out.println(" const type = NameAndType");

n16 = input.readShort();

System.out.println(" name index = " + n16 + " (where to find the name)");

n16 = input.readShort();

System.out.println(" descripter = " + n16 + " (where to find the descriptor)");

break;

default:

throw new RuntimeException("Invalid constant pool flag: " + flag);

}

}

}

输出结果为:

magic number = 0xCAFEBABE

Version = 48.0

constant pool size = 22

const index = 1, flag = 1

const type = Utf8

length = 22

value = example/test/TestClass

const index = 2, flag = 7

const type = Class

index = 1 (where to find the class name)

const index = 3, flag = 1

const type = Utf8

length = 16

value = java/lang/Object

const index = 4, flag = 7

const type = Class

index = 3 (where to find the class name)

const index = 5, flag = 1

const type = Utf8

length = 2

value = id

const index = 6, flag = 1

const type = Utf8

length = 1

value = I

const index = 7, flag = 1

const type = Utf8

length = 6

value =

const index = 8, flag = 1

const type = Utf8

length = 3

value = ()V

const index = 9, flag = 1

const type = Utf8

length = 4

value = Code

const index = 10, flag = 12

const type = NameAndType

name index = 7 (where to find the name)

descripter = 8 (where to find the descriptor)

const index = 11, flag = 10

const type = Methodref

class index = 4 (where to find the class)

nameAndType = 10 (where to find the NameAndType)

const index = 12, flag = 3

const type = Integer

value = 1234567

const index = 13, flag = 12

const type = NameAndType

name index = 5 (where to find the name)

descripter = 6 (where to find the descriptor)

const index = 14, flag = 9

const type = Fieldref

class index = 2 (where to find the class)

nameAndType = 13 (where to find the NameAndType)

const index = 15, flag = 1

const type = Utf8

length = 15

value = LineNumberTable

const index = 16, flag = 1

const type = Utf8

length = 18

value = LocalVariableTable

上一篇:制作阴影效果的表格

下一篇:网页中相关事件的详细讲解和说明