一。类加载器
1.类加载器 ClassLoader
BootStrp. 加载JRE/lib/rt.jar
ExtClassLoader. 加载/JRE/lib/ext/*.jar
AppClassLoader CLPSSPATH指定的所有jar和目录
2.委托机制(类加载器)
Thread.setContextClassLoader(ClassLoader )//设定当前线程的加载器。
起始加载器可以是:
2.1.首先当前线程的类加载器去加载线程中的第一个类。
2.2.如果类A中引用类B,jvm将使用加载类A的类装载器来加载B
2.3.还可以直接调用ClassLoader.loaderClass()方法来指定某个类加载器去加载
每个类加载器加载类时,先委托给其上级类加载器。
当所有祖宗类加载器没有加载到类,回到发起者类加载器,还不能加载
,则抛ClassNotFoundException,不是再去找发起者类加载器的儿子,因为没有
getChiled方法,即使有,那有多个儿子,找哪 一个呢?
3.能不自己写一类叫java.lang.System。
类加载采用委托机制,这样可以保证爸爸们优先,也就是总是使用爸爸们能找到的类,
这样总是使用JAVA系统提供的System。
4.自定义加载器
得到Class文件转换成字节码-->definclass()
继承ClassLoader Override findClass(String name)
调用 Class ss= new MyClassLoader("itcastlib").loaderClass("");
//加载的类如果不同包要是public class,有自定义的构造方法。
public class MyClassLoader extends ClassLoader {
String dirPath;
public MyClassLoader(String dirPath) {
this.dirPath = dirPath;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
String fileName=dirPath+"//"+name+".class";
try {
InputStream ips=new FileInputStream(fileName);
ByteArrayOutputStream baIps=new ByteArrayOutputStream();
int i;
while((i=ips.read())!=-1)
{
baIps.write(i&255);
baIps.flush();
}
ips.close();
byte[] bts=baIps.toByteArray();
baIps.close();
return defineClass(bts, 0, bts.length);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return super.findClass(name);
}
}
|