。清单 2 中的类显示了这一 递归装入的工作方式。 Demo 类包含一个简单的 main 方法,它创建了 Greeter 的实例,并 调用 greet 方法。 Greeter 构造函数创建了 Message 的实例,随后会在 greet 方法调用 中使用它。
清单 2. 类装入演示的源代码
public class Demo
{
public static void main(String[] args) {
System.out.println("**beginning execution**");
Greeter greeter = new Greeter();
System.out.println("**created Greeter**");
greeter.greet();
}
}
public class Greeter
{
private static Message s_message = new Message("Hello, World!");
public void greet() {
s_message.print(System.out);
}
}
public class Message
{
private String m_text;
public Message(String text) {
m_text = text;
}
public void print(java.io.PrintStream ps) {
ps.println(m_text);
}
}
Java编程的动态性,第1部分: 类和类装入(3)
时间:2011-04-09 IBM Dennis M. Sosnoski
在 java 命令行上设置参数 -verbose:class 会打印类装入过程的跟踪记录。清单 3 显 示了使用这一参数运行清单 2 程序的部分输出:
清单 3. -verbose:class 的部分输出
[Opened /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Opened /usr/java/j2sdk1.4.1/jre/lib/sunrsasign.jar]
[Opened /usr/java/j2sdk1.4.1/jre/lib/jsse.jar]
[Opened /usr/java/j2sdk1.4.1/jre/lib/jce.jar]
[Opened /usr/java/j2sdk1.4.1/jre/lib/charsets.jar]
[Loaded java.lang.Object from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.io.Serializable from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.lang.Comparable from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.lang.CharSequence from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.lang.String from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
...
[Loaded java.security.Principal from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.security.cert.Certificate
from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded Demo]
**beginning execution**
[Loaded Greeter]
[Loaded Message]
**created Greeter**
Hello, World!
[Loaded java.util.HashMap$KeySet
from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.util.HashMap$KeyIterator
from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
这只列出了输出中最重要的部分 ― 完整的跟踪记录由 294 行组成,我删除了其中大部 分,形成了这个清单。最初的一组类装入(本例中是 279 个)都是在尝试装入 Demo 类时触 发的。这些类是每个 Java 程序(不管有多小)都要使用的核心类。即使删除 Demo main 方 法的所有代码也不会影响这个初始的装入顺序。但是不同版本的类库所涉及的类数量和名称 都不同。
在上面这个清单中,装入 Demo 类之后的部分更有趣。这里的顺序显示了只有在准备创建 Greeter 类的实例时才会装入该类。不过, Greeter 类使用了 Message 类的静态实例,所 以在可以创建 Greeter 类的实例之前,还必须先装入 Message 类。
在装入并初始化类时,JVM 内部会完成许多操作,包括解码二进制类格式、检查与其它类 的兼容性、验证字节码操作的顺序以及最终构造 java.lang.Class 实例来表示新类。这个 Class 对象成了 JVM 创建新类的所有实例的基础。它还是已装入类本身的标识 ― 对于装入 到 JVM 的同一个二进制类,可以有多个副本,每个副本都有其 |