background image

 

第 部分类和类装入

 

本文是这个新系列文章的第一篇,该系列文章将讨论我称之为 Java 编程的动
态性

 

的一系列主题。这些主题的范围从 Java 二进制类文件格式的基本结构,

以及使用反射进行运行时元数据访问,一直到在运行时修改和构造新类。贯穿

 

整篇文章的公共线索是这样一种思想:在 Java 平台上编程要比使用直接编译
成本机代码的语言更具动态性。如果您理解了这些动态方面,就可以使用 
Java 

 

编程完成那些在任何其它主流编程语言中不能完成的事情。

 

本文中,我将讨论一些基本概念,它们是这些 Java 平台动态特性的基础。这

 

些概念的核心是用于表示 Java 

 

类的二进制格式,包括这些类装入到 JVM 时

所发生的情况。本文不仅是本系列其余几篇文章的基础,而且还演示了开发人

 

员在使用 Java 平台时碰到的一些非常实际的问题。

用二进制表示的类

 

使用 Java 语言的开发人员在用编译器编译他们的源代码时,通常不必关心对
这些源代码做了些什么这样的细节。但是本系列文章中,我将讨论从源代码到
执行程序所涉及的许多幕后细节,因此我将首先探讨由编译器生成的二进制
类。

 

二进制类格式实际上是由 JVM 规范定义的。通常这些类表示是由编译器从 
Java 

 

语言源代码生成的,而且它们通常存储在扩展名为 .class 的文件中。但

 

是,这些特性都无关紧要。已经开发了可以使用 Java 二进制类格式的其它一
些编程语言,而且出于某些目的,还构建了新的类表示,并被立即装入到运

 

行中的 JVM

 

。就 JVM 而言,重要的部分不是源代码以及如何存储源代码,而

 

是格式本身。

 

那么这个类格式实际看上去是什么样呢?清单 1 提供了一个(非常)简短的
类的源代码,还附带了由编译器输出的类文件的部分十六进制显示:

 

清单 1. Hello.java 的源代码和(部分)二进制类文件

public class Hello
{
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
0000: cafe babe 0000 002e 001a 0a00 0600 0c09  ................
0010: 000d 000e 0800 0f0a 0010 0011 0700 1207  ................
0020: 0013 0100 063c 696e 6974 3e01 0003 2829  .....<init>...()