ClassLoader编程实践

Java类加载器编程实践

SEP 8TH, 2013 | COMMENTS

文本通过实现自定义类加载器,实践 Java 类加载的流程。

阅读此文前,需要了解 Java 类加载的基本原理,参见如下两篇博文:

以上博文中所提及的 Java 类加载机制,都是 Java1.2 及以后的版本,而在最早的 Java1.1 中类加载器是没有父子关系的模式的。这里将分别对 Java1.1 和 Java1.2 及以后的类加载版本进行展示。

Java1.1 中的实现

原理介绍

Java1.1 的类加载机制相对单一,用户自定义加载器的重写比较复杂。

主要需要重写加载器中的 Class loadClass(String name)方法。

Class loadClass(String name)或 loadClass(String name , boolean resolve)方法是加载的核心。它根据类的全名(比如 String 类的全名是 java.lang.String)获得对应类的二进制数据,然后通过 Class defineClass(byte[] b) 将二进制数据加载到 JVM 的方法区,并返回对应类的 Class 实例,然后根据可选的参数 resolve 决定是否需要现在解析这个类。最后将这个 Class 实例作为 loadClass 方法的返回值。

如果无法加载和 defineClass,即无法通过本加载器直接加载类的情况,则使用 Class findSystemClass(String name) 将类加载任务委派给系统类加载器查找。如果能找到则加载,否则抛出 ClassNotFoundException 异常。

编程实例

以下用实例来展示这一过程:

类 CompilingClassLoader 是一个自定义加载器,它能直接读取 Java 源文件实现类加载。CLL 类的 main 方法为程序入口,通过 ComplilingClassLoader 加载一个 Foo 类,使用反射机制调用 Foo 类的 main 方法。

CompilingClassLoader.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import java.io.*;

/* 
 
A CompilingClassLoader compiles your Java source on-the-fly.  It 
checks for nonexistent .class files, or .class files that are older 
than their corresponding source code. 
 
*/

public class CompilingClassLoader extends ClassLoader
{
             
  // Given a filename, read the entirety of that file from disk  
  // and return it as a byte array.  
  private byte[] getBytes( String filename ) throws IOException {
             
    // Find out the length of the file  
    File file = new File( filename );
    long len = file.length();

    // Create an array that's just the right size for the file's  
    // contents  
    byte raw[] = new byte[(int)len];

    // Open the file  
    FileInputStream fin = new FileInputStream( file );

    // Read all of it into the array; if we don't get all,  
    // then it's an error.  
    int r = fin.read( raw );
    if (r != len)
      throw new IOException( "Can't read all, "+r+" != "+len );

    // Don't forget to close the file!  
    fin.close();

    // And finally return the file contents as an array  
    return raw;
  }

  // Spawn a process to compile the java source code file  
  // specified in the 'javaFile' parameter.  Return a true if  
  // the compilation worked, false otherwise.  
  private boolean compile( String javaFile ) throws IOException {
             
    // Let the user know what's going on  
    System.out.println( "CCL: Compiling "+javaFile+"..." );

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值