//学习来源:网络或教科书
//自动定义类加载器--AppClassLoader--ExtClassLoader--bootstrap ClassLoader
//系统默认类加载流程:双亲委托机制--先交由父类加载器加载,如果父类加载不了再回溯给子类加载器加载//线程上下文类加载器,可以摒弃,默认的加载流程。
public class ClassLoaderTest {
public static void main(String [] args) throws IOException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException{
//测试类 bin/classloader/Test.class
//java核心类的加载,由ExtClassLoader--bootstrap ClassLoader加载
MyLoader myloader1=new MyLoader();
Class<?> c1=myloader1.findClass("java.lang.String");
System.out.println(c1.getClassLoader());// null 根加载器
MyLoader myloader2=new MyLoader();
String path1="classloader.Test";//包名.类名,当前App,bin目录下的Test.class,文件
Class<?> c2=myloader2.findClass(path1);//模拟默认加载器加载类的流程
System.out.println(c2.getClassLoader());//应用程序(系统)加载器
MyLoader myloader=new MyLoader("D:/java/");
String path="HelloWorld";//其他存储位置的 类.class文件的类名
Class<?> clazz=myloader.myLoader(path);//自定义加载器
System.out.println(clazz.getClassLoader());//MyLoader
Object o= clazz.newInstance();
try {
//调用Test的hello方法
clazz.getMethod("hello", null).invoke(o, null);
} catch (IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
//线程上下文类加载器
ClassLoader threadLoader=Thread.currentThread().getContextClassLoader();
Class threadClazz=threadLoader.loadClass("classloader.Test");
System.out.println(threadClazz.getClassLoader());
Thread.currentThread().setContextClassLoader(new MyLoader("D:/java/"));
System.out.println(Thread.currentThread().getContextClassLoader());
}
}
//自定义类加载器
class MyLoader extends ClassLoader{
String dir;
public MyLoader() {
}
public MyLoader(String dir) {
super();
this.dir = dir;
}
/**
* 自定义加载器,按你的想法,来加载
* @param name
* @return
*/
protected Class<?> myLoader(String name){
byte[] classCode=getClassCode(name);
if(null==classCode){
try {
throw new ClassNotFoundException();
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}else{
return this.defineClass(name, classCode, 0, classCode.length);
}
}
/**
* 模拟java默认类加载器加载流程
*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> c=this.findLoadedClass(name);
//查看有没有加载过,如果有直接返回
if(null!=c){
return c;
}else{
ClassLoader parentloader=this.getParent();//1.给父类加载器加载
try{
c=parentloader.loadClass(name);
}catch(Exception e){
//e.printStackTrace();
}
if(null!=c){
return c;
}else{
byte[] classCode=getClassCode(name);
if(null==classCode){
throw new ClassNotFoundException();
}else{
return this.defineClass(name, classCode, 0, classCode.length);
}
}
}
}
//==========
public byte[] getClassCode(String name){
StringBuilder sb=new StringBuilder("");
if(null==this.dir||"".equals(this.dir)){
sb.append(Thread.currentThread().getContextClassLoader().getResource(".").getPath()).append(name.replace('.', '/')).append(".class");
}else{
sb.append(this.dir).append(name).append(".class");
}
String url=sb.toString();
InputStream is = null;
ByteArrayOutputStream bos=new ByteArrayOutputStream();
try {
is=new FileInputStream(new File(url));
byte[] buffer=new byte[1024];
int len=0;
while((len=is.read(buffer))!=-1){
bos.write(buffer, 0, len);
if(len<1024)break;
}
bos.flush();
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(null!=is){
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}