[Home]   [TOC]

Study_Java_ByteCode  
Java ByteCode Study
Updated Sep 4, 2012 by jht5...@gmail.com

1. Class格式及字节码介绍

Class文件的格式如下 [6]

struct Class_File_Format {
   u4 magic_number;   // HEX:CAFEBABE
   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];
}

详细说明请参看:Class格式

字节码指令介绍

那么,字节码是如何执行的?
先看一下下面一段Java代码:

int i = 1;
int j = 3;
int sum = i + j;
System.out.println(sum);

通过javac编译,并javap -v反编译以上代码:

Code:
   Stack=2, Locals=4, Args_size=1
   0:     iconst_1
   1:     istore_1
   2:     iconst_3
   3:     istore_2
   4:     iload_1
   5:     iload_2
   6:     iadd
   7:     istore_3
   8:     getstatic     #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   11:     iload_3
   12:     invokevirtual     #3; //Method java/io/PrintStream.println:(I)V
   15:     return
  LineNumberTable:
   line 4: 0
   line 5: 2
   line 6: 4
   line 7: 8
   line 8: 15

直接打印出class文件的相关内容为:

04 3c 06 3d 1b 1c 60 3e b2 00 02 1d b6 00 03 b1

对以上class内容反编译 [5]如下:

04  iconst_1
3c  istore_1
06  iconst_3
3d  istore_2
1b  iload_1
1c  iload_2
60  iadd
3e  istore_3
b2  getstatic [ constant pool index = index1 << 8 + index2, here is "2" ]
00      index1
02      index2
1d  iload_3
b6  invokevirtual [ constant pool index = index1 << 8 + index2, here is "3" ]
00      index1
03      index2
b1  return

JVM中执行bytecode是在栈上执行的,以上字节码是这样运行的:

2. 字节码操纵框架

ASM http://asm.ow2.org/ ObjectWeb ASM轻量级的Java字节码处理框架。它可以动态生成二进制格式的stub类或其他代理类,或者在类被JAVA虚拟机装入内存之前,动态修改类。ASM 提供了与 BCEL和SERP相似的功能,只有22K的大小,比起350K的BCEL和150K的SERP来说,是相当小巧的,并且它有更高的执行效率,是BCEL的7倍,SERP的11倍以上。 [1]
BCEL http://commons.apache.org/bcel/ Byte Code Engineering Library (BCEL),这是Apache Software Foundation 的Jakarta 项目的一部分。BCEL是 Java classworking 最广泛使用的一种框架,它可以让您深入 JVM 汇编语言进行类操作的细节。BCEL与Javassist 有不同的处理字节码方法,BCEL在实际的JVM 指令层次上进行操作(BCEL拥有丰富的JVM 指令级支持)而Javassist 所强调的源代码级别的工作。 [1]
Javassist http://www.javassist.org/ Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态AOP框架。 [1]
cglib http://cglib.sourceforge.net/ cglib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。Hibernate用它来实现PO字节码的动态生成。 [1]
jclasslib http://www.ej-technologies.com/products/jclasslib/overview.html JClassLib不但是一个字节码阅读器而且还包含一个类库允许开发者读取,修改,写入Java Class文件与字节码。 [1]

3. 反编译软件

jd http://java.decompiler.free.fr/ JD分为JD-GUI、JD-Eclipse两种运行方式,JD-GUI是以单独的程序的方式运行,JD-Eclipse则是以一个Eclipse插件的方式运行。 [2]
jad http://www.varaneckas.com/jad/ jad 是一个使用非常广泛的 Java 反编译工具。 [3]

参考资料

[1]. http://www.open-open.com/54.htm
[2]. http://baike.baidu.com/view/1872199.htm
[3]. http://www.oschina.net/p/jad
[4]. http://aprilsoft.cn/blog/post/308.html
[5]. http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
[6]. http://en.wikipedia.org/wiki/Java_class_file