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
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classData = null;
try {
classData = loadClassData(name);
} catch (IOException e) {
e.printStackTrace();
}
/**
* 根据类名字符串加载类 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
*
*/
}
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
*
*/
}