JVM的类加载器与双亲委派模型
类加载器
-
启动类加载器(Bootstrap ClassLoader):
加载java的核心类,无法被java程序直接引用。
-
扩展类加载器(ectensions class loader):
加载java扩展目录下的一些指定的类库。
-
系统类加载器(System class loader):
加载开发时指定目录下的代码,一般来说java应用的类的加载都是通过它来完成的。
-
自定义加载器:
继承ClassLoader,重写findClass。例如:
public class MyClassload extends ClassLoader{ @Override protected Class<?> findClass(String name) { try{ String className = name+".class"; File file = new File("E:\\aaaaa",className); FileInputStream fileInputStream = new FileInputStream(file); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] b = new byte[1024]; //读文件 int len = fileInputStream.read(b); byteArrayOutputStream.write(b,0,len); byte[] datas = byteArrayOutputStream.toByteArray(); return defineClass(name,datas,0,datas.length); }catch (Exception e){ e.printStackTrace(); return null; } } }
public static void main(String[] args) throws Exception { MyClassload myClassload = new MyClassload(); Class test = myClassload.loadClass("Test"); System.out.println(test.getName()); }
双亲委派
当加载器加载文件时,先看上级加载器能否加载,如果能加载就进行加载,不能加载再由本级来加载。
如果有同包同类名的两个类出现,不会都进行加载,并会抛出java.lang.SecurityException
例如:
public class MyClassload extends ClassLoader{
@Override
protected Class<?> findClass(String name) {
try{
String className = name+".class";
File file = new File("E:\\aaaaa",className);
FileInputStream fileInputStream = new FileInputStream(file);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] b = new byte[1024];
//读文件
int len = fileInputStream.read(b);
byteArrayOutputStream.write(b,0,len);
byte[] datas = byteArrayOutputStream.toByteArray();
//测试就写死了
return defineClass("java.lang."+name,datas,0,datas.length);
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
public static void main(String[] args) throws Exception {
MyClassload myClassload = new MyClassload();
Class string = myClassload.loadClass("String");
System.out.println(string.getName());
}
结果:
java.lang.SecurityException: Prohibited package name: java.lang
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:662)
at java.lang.ClassLoader.defineClass(ClassLoader.java:761)
at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
at classload.MyClassload.findClass(MyClassload.java:23)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at MainClass.main(MainClass.java:30)
Exception in thread "main" java.lang.NullPointerException
at MainClass.main(MainClass.java:31)
Process finished with exit code 1