候捷谈Java反射机制(三)

Java 源码改动办法
先前我曾提到,原本想借由“改动 Java 标准库源码”来测知 Class object 的生成,但由于其 ctor 原始设计为 private ,也就是说不可能透过这个管道生成 Class object (而是由 class loader 负责生成),因此“在 ctor 打印出某种信息”的企图也就失去了意义。
这里我要谈点题外话:如何修改 Java 标准库源码并让它反应到我们的应用程序来。假设我想修改 java.lang.Class ,让它在某些情况下打印某种信息。首先必须找出标准源码!当你下载 JDK 套件并安装妥当,你会发现 jdk150\src\java\lang 目录(见 10 )之中有 Class.java ,这就是我们此次行动的标准源码。备份后加以修改,编译获得 Class.class 。接下来准备将 .class 搬移到 jdk150\jre\lib\endorsed (见 10 )。
这是一个十分特别的目录, class loader 将优先从该处读取内含 classes .jar 文件 —— 成功的条件是 .jar 内的 classes 压缩路径必须和 Java 标准库的路径完全相同。为此,我们可以将刚才做出的 Class.class 先搬到一个为此目的而刻意做出来的 \java\lang 目录中,压缩为 foo.zip (任意命名,唯需夹带路径 java\lang ),再将这个 foo.zip 搬到 jdk150\jre\lib\endorsed 并改名为 foo.jar 。此后你的应用程序便会优先用上这里的 java.lang.Class 。整个过程可写成一个批处理文件( batch file ),如 11 ,在 DOS Box 中使用。
10 JDK1.5 安装后的目录组织。其中的 endorsed 是我新建。
del e:\java\lang\*.class // 清理干净
del c:\jdk150\jre\lib\endorsed\foo.jar // 清理干净
c:
cd c:\jdk150\src\java\lang
javac -Xlint:unchecked Class.java // 编译源码
javac -Xlint:unchecked ClassLoader.java / / 编译另一个源码(如有必要)
move *.class e:\java\lang // 搬移至刻意制造的目录中
e:
cd e:\java\lang // 以下压缩至适当目录
pkzipc -add -path=root c:\jdk150\jre\lib\endorsed\foo.jar *.class
cd e:\test // 进入测试目录
javac -Xlint:unchecked Test.java // 编译测试程序
java Test // 执行测试程序
11 :一个可在 DOS Box 中使用的批处理文件( batch file ),用以自动化 java.lang.Class
的修改动作。 Pkzipc(.exe) 是个命令列压缩工具, add path 都是其命令。
更多信息
以下是视野所及与本文主题相关的更多讨论。这些信息可以弥补因文章篇幅限制而带来的不足,或带给您更多视野。
l " Take an in-depth look at the Java Reflection API -- Learn about the new Java 1.1 tools forfinding out information about classes ", by Chuck McManis 。此篇文章所附程序代码是本文示例程序的主要依据(本文示例程序示范了更多 Reflection APIs ,并采用 JDK1.5 新式的 for-loop 写法)。
l " Take a look inside Java classes -- Learn to deduce properties of a Java class from inside aJava program ", by Chuck McManis
l " The basics of Java class loaders -- The fundamentals of this key component of the Javaarchitecture ", by Chuck McManis
l The Java Tutorial Continued , Sun microsystems. Lesson58-61, "Reflection".
1 用过诸如 MFC 这类所谓 Application Framework 的程序员也许知道, MFC 有所谓的 dynamic creation 。但它并不等同于 Java 的动态加载或动态辨识;所有能够在 MFC 程序中起作用的 classes ,都必须先在编译期被编译器 看见
2 如果操作对象是 Object Class.getSuperClass() 会返回 null

你可能感兴趣的:(java,C++,c,dos,mfc)