**Java 字节码**（英語：）是Java虚拟机执行的一种指令格式。大多数操作码（英语：）都是一个字节长，而有些操作需要参数，导致了有一些多字节的操作码。而且并不是所有可能的256个操作码都被使用；其中有51个操作码被保留做将来使用。除此之外，原始Java平台开发商，昇陽微系统，额外保留了3个代码永久不使用。

与Java的关系
--------

一个Java程序员并不需要理解所有的Java字节码。但是，就像IBM developerWorks周刊建议的那样："理解字节码以及理解Java编译器如何生成Java字节码与学习汇编知识对于C/C++程序员有一样的意义。"

指令
--

每一个字节，有256个可能的代码值（28=256），因此一个字节的操作码最多可能有256种不同的操作。其中，0x00、0xFE、0xCA、0xFF被指定保留。例如0xCA作为一个Java调试器的中断指令而从未被语言使用。相似地，0xFE和0xFF也未被语言使用。

指令可以基本分为以下几类：

* 存储指令 （例如：aload\_0, istore）
* 算术与逻辑指令 （例如: ladd, fcmpl）
* 类型转换指令 （例如：i2b, d2i）
* 对象创建与操作指令 （例如：new, putfield）
* 堆栈操作指令 （例如：swap, dup2）
* 控制转移指令 （例如：ifeq, goto）
* 方法调用与返回指令 （例如：invokespecial, areturn)

除此之外，还有一些更特殊的指令，作为异常抛出或同步等作用。

大多数的指令有前缀和（或）后缀来表明其操作数的类型。如下表

| 前/后缀 | 操作数类型 |
| --- | --- |
| `i` | 整数 |
| `l` | 长整数 |
| `s` | 短整数 |
| `b` | 字节 |
| `c` | 字符 |
| `f` | 单精度浮点数 |
| `d` | 双精度浮点数 |
| `z` | 布尔值 |
| `a` | 引用 |

例如，"iadd"指令将两个整数相加；而"dadd"指令将两个double浮点数相加。 此外，"const"、 "load"、 "store"等命令还会使用"\_n"后缀，其中 "load"和"store"命令中的*n*可以为0到3之间的整数；而"const"命令中的n由类型指定。
"const"指令把一个指定类型的值放入堆栈。例如"iconst\_5"指令将一个整数5放入堆栈；而"dconst\_1"将一个双精度浮点数1放入堆栈。
此外还有"aconst\_null"指令，放入一个null进堆栈。而对于"load" "store"指令中的n，指定了变量表中的存储位置。"aload\_0"指令把在变量0中的对象（通常是"this"对象）放入堆栈，"istore\_1"指令把栈顶的一个整数放入变量1.对于更高的变量，后缀将被去除，而这条指令将需要操作数。

计算模型
----

Java字节码的计算模型是面向堆栈结构计算机的。例如，一个x86处理器的汇编代码如下

```
mov eax, byte [ebp-4]
mov edx, byte [ebp-8]
add eax, edx
mov ecx, eax

```

这段代码将两个数值相加，并存入另一个地址。相似的反汇编字节码如下

```
0 iload\_1
1 iload\_2
2 iadd
3 istore\_3

```

在这里，需要相加的两个操作数被放入堆栈，而相加操作就在栈中进行，其结果也被放入堆栈。存储指令之后把栈顶的数据放入一个变量地址。在每条指令前面的数字仅仅是表示这条指令到方法开始处的偏移值。这种堆栈结构也可以推广到面向对象模型上。例如，有一个"getName"方法如下

```
 Method java.lang.String getName()
 0 aload\_0 // "this"对象被存入变量0
 1 getfield #5 <Field java.lang.String name>
 // 这个指令从栈顶取出一个对象，并从中搜索一个指定的域
 // 并将相应的数据存入栈顶。
 // 这个例子中，"name"域对应于该类中的第五个常量。
 
 4 areturn // 返回栈顶的对象作为函数的返回值

```

例子
--

考虑如下Java代码

```
 outer:
 for (int i = 2; i < 1000; i++) {
 for (int j = 2; j < i; j++) {
 if (i % j == 0)
 continue outer;
 }
 System.out.println (i);
 }

```

假设上述代码位于一个函数中，Java编译器可能将代码翻译成下述的Java字节码。

```
 0: iconst\_2
 1: istore\_1
 2: iload\_1
 3: sipush 1000
 6: if\_icmpge 44
 9: iconst\_2
 10: istore\_2
 11: iload\_2
 12: iload\_1
 13: if\_icmpge 31
 16: iload\_1
 17: iload\_2
 18: irem
 19: ifne 25
 22: goto 38
 25: iinc 2, 1
 28: goto 11
 31: getstatic #84; //Field java/lang/System.out:Ljava/io/PrintStream;
 34: iload\_1
 35: invokevirtual #85; //Method java/io/PrintStream.println:(I)V
 38: iinc 1, 1
 41: goto 2
 44: return

```

基于Java字节码的语言
------------

最常用的基于Java字节码的语言就是开发出Java字节码的Java语言。刚开始，只存在一个由昇陽微系统开发的一个编译器javac。而现在Java字节码规范已经可以得到，因此，第三方公司亦开发出支持Java字节码的编译器。例如：

* Jikes，编译Java源代码到Java字节码（由IBM开发，用C++实现）
* Espresso，编译Java源代码到Java字节码（仅支持Java 1.0）
* GCJ，GNU Compiler for Java，编译Java代码到Java字节码；亦可以编译到机器代码。作为GNU Compiler Collection (GCC)的一部分提供。

有一些项目提供Java汇编器以便于直接用Java字节码进行开发。主要的Java汇编器如下：

* Jasmin，读取Java类的文字描述；用一种简单的使用Java虚拟机指令的类汇编语法，输出Java类文件
* Jamaica， 一种为Java虚拟机编写的宏汇编语言。其中，类与接口由Java语法定义，而其中的方法却由Java字节码定义。

还有其他的一些编译器，对于其他语言生成Java字节码，使其可以运行在Java虚拟机之上。

* ColdFusion
* JRuby和Jython， 两种基于Ruby和Python的脚本语言
* Groovy, 一种基于Java的脚本语言
* Scala,一种类型安全的通用编程语言，支持面向对象编程和函数式编程
* JGNAT和AppleMagic,编译Ada语言到Java字节码
* Clojure, 一种函数式的通用编程语言，提供优秀的并发性。是一种LISP方言
* MIDletPascal
* JavaFX Script 由昇陽微系统公司开发的一种脚本语言，运行于Java虚拟机之上

运行
--

当前已经有很多种Java虚拟机产品，包括了自由软件和商业软件。
如果在Java虚拟机之中执行Java字节码并不理想，则可以使用一些工具例如GNU Compiler for Java将Java代码或Java字节码编译成机器码并由硬件直接运行。
而有一些处理器可以直接运行Java字节码，这种处理器名为Java处理器。

对动态语言的支持
--------

Java虚拟机对动态类型语言提供了一定的支持。但绝大多数的Java虚拟机指令集是基于静态类型语言的。在静态类型机制下，方法调用中的类型分析都是在编译时执行的，而且缺乏一种机制在运行时确定一个类型已经确定相应的方法。

JSR292中，在Java虚拟机层次增加了一种支持动态类型的指令`invokedynamic`，以支持在动态类型检测中的方法调用。 达芬奇机器（英语：）则是一种支持这种动态类型调用的虚拟机。 而所有支持JSE 7的Java虚拟机都应支持invokedynamic操作码。

参考文献
----

1. ↑ .  [2014-01-28]. （原始内容存档于2008-12-08）.
2. ↑ .  [2014-01-28]. （原始内容存档于2013-02-21）.
3. ↑ .  [2020-06-21]. （原始内容存档于2020-04-17）.
4. ↑ .  [2014-01-28]. （原始内容存档于2012-06-24）.
5. ↑ .  [2014-01-28]. （原始内容存档于2020-12-20）.

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
Java |
| --- |
|  |
| Java平臺 | 
* Java
	+ Java版本歷史
	+ Java 5.0
* JVM
	+ Java字节码
* Java ME
* Java SE
* Java EE
* Java Card
* Android SDK

 |  |
|  |
| Oracle技术 | 
* Squawk（英语：）
* JDK
* OpenJDK
* Java虚拟机
* JavaFX
* Maxine VM（英语：）

 |
|  |
| 平台技术 | 
* Java集合框架
* Servlets
* MIDlet（英语：）
* JSP
* Web Start (JNLP)（英语：）
* applet

 |
|  |
| 主要的第三方技术 | 
* Blackdown（英语：）
* Eclipse
* GNU Classpath
* GWT
* Harmony
* Hibernate
* IcedTea（英语：）
* Jazelle（英语：）
* Spring
* Struts
* TopLink
* WildFly

 |
|  |
| 历史 | 
* Java版本歷史
* JCP
* 昇陽電腦
* 自由的Java实现

 |
|  |
| 主要JVM语言（英语：） | 
* BeanShell（英语：）
* Clojure
* Groovy
* Oxygene（英语：）
* JRuby
* Jython
* Kotlin
* Processing
* Rhino
* Scala
* Tcl/Java（英语：）

 |
|  |
| 会议（英语：） | 
* JavaOne
* Devoxx（英语：）

 |

 |