一个 Java classloader 的例子

来源:互联网 发布:3阶矩阵的2范数怎么求 编辑:程序博客网 时间:2024/05/06 15:26
package reflection;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;


public class MyClassLoader extends ClassLoader {

public static void main(String[] args) throws 
ClassNotFoundException, InstantiationException, IllegalAccessException, 
IllegalArgumentException, InvocationTargetException {

ClassLoader loader = Thread.currentThread().getContextClassLoader();  
System.out.println("list hierarchy of class loader"); 
/* output:
*sun.misc.Launcher$AppClassLoader@387f44
*sun.misc.Launcher$ExtClassLoader@19e0bfd
*
 Here, ExtClassLoader's parent (bootstrap classloader) is NULL 
as bootstrap class loader is not written in Java
*/
        while (loader != null) {   
            System.out.println(loader.toString());   
            loader = loader.getParent();   
        }   
    
MyClassLoader fileClsLoader = new MyClassLoader();
loader=fileClsLoader.getParent();
/* Output:
* sun.misc.Launcher$AppClassLoader@387f44
* so user-defined ClassLoader's parent is AppClassLoader
*/
System.out.println(loader.toString());  

fileClsLoader.setClassPath("C:\\Users\\hongbin\\workspace\\ClassLoadAndReflection\\bin");
Class cls = fileClsLoader.loadClass("reflection.MyTest");
Object obj = cls.newInstance();
Method[] mthds = cls.getMethods();
for(Method mthd : mthds){
String methodName = mthd.getName();
System.out.println("method.name="+methodName);
 }
}

private String classPath;
/**

 * 根据类名字符串从指定的目录查找类,并返回类对象

这是我们 override的method

 */
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classData = null;
try {
classData = loadClassData(name);
} catch (IOException e) {
e.printStackTrace();

}

//this method is Java system's final method  and can't be overriden 

return super.defineClass(name, classData, 0, classData.length);
}
 
/**
 * 根据类名字符串加载类 byte 数据流
 * @param name   class name String 例如: reflection.MyTest
 * @return   返回类文件 byte 流数据
 * @throws IOException
 */
private byte[] loadClassData(String name) throws IOException{
File file = getFile(name);
FileInputStream fis = new FileInputStream(file);
byte[] arrData = new byte[(int)file.length()];
fis.read(arrData);
fis.close();
return arrData;
}
 
/**
 * return FILE object per class name (it includes, if any, package name)
 * @param name   类名字符串   
 * @return    File 对象
 * @throws FileNotFoundException
 */
private File getFile(String name) throws FileNotFoundException {
File dir = new File(classPath);
if(!dir.exists()) 
throw new FileNotFoundException(classPath+" 目录不存在!");
String _classPath = classPath.replaceAll("[\\\\]", "/");
System.out.println("my class path="+ (_classPath));
int offset = _classPath.lastIndexOf("/");
name = name.replaceAll("[.]", "/");
System.out.println("my class result name="+ (name));
 
if(offset != -1 && offset < _classPath.length()-1){
_classPath += "/";
}
//completed file name with absolute path
 
_classPath += name +".class";
dir = new File(_classPath);
if(!dir.exists()) throw new FileNotFoundException(dir+" 不存在!");
return dir;
}
 
public String getClassPath() {
return classPath;
}
 
public void setClassPath(String classPath) {
this.classPath = classPath;
}
 
// output of run results:
  
/* list hierarchy of class loader
sun.misc.Launcher$AppClassLoader@387f44
sun.misc.Launcher$ExtClassLoader@19e0bfd
sun.misc.Launcher$AppClassLoader@387f44
my class path=C:/Users/hongbin/workspace/ClassLoadAndReflection/bin
my class result name=reflection/MyTest
method.name=getName
method.name=getID
method.name=wait
method.name=wait
method.name=wait
method.name=equals
method.name=toString
method.name=hashCode
method.name=getClass
method.name=notify
method.name=notifyAll
 * 
 */
}
0 0