以下是Classloader的中最重要的方法,也就是所谓的双亲委派模型。这个模型第一次在周志明的书上看到,当时看了只知道是类加载过程是首先是委托给父加载器,否则父不能加载,则自己加载,整个过程实则是一个很简单的递归过程,本文以实例讲解这个模型到底是咋实现的? protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); } } if (resolve) { resolveClass(c); } return c; } }
类加载器用来测试的Class文件对应的类
public class TestLoaderClass { public TestLoaderClass() { System.out.println("加载器为"+TestLoaderClass.class.getClass()); } }
//自定义类加载器import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteOrder; public class MyClassLoader extends ClassLoader { //类加载器名称 private String name; //加载类的路径 private String path = "D:/"; private final String fileType = ".class"; public MyClassLoader(String name){ //让系统类加载器成为该 类加载器的父加载器 super(); this.name = name; } //显示设置类加载器的父类加载器 public MyClassLoader(ClassLoader parent, String name){ //显示指定该类加载器的父加载器 super(parent); this.name = name; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } @Override public String toString() { return this.name; } /** * 获取.class文件的字节数组 * @param name * @return */ /** * 获取Class对象 * @throws IOException */ private byte[] getBytes(String name) throws IOException { //name=name.replace(".", "/"); File f=new File(path+name+fileType); InputStream in=new FileInputStream(f); System.out.println(in.available()+"file"); ByteArrayOutputStream bao=new ByteArrayOutputStream(); int r=in.read(); while(r!=-1) { bao.write(r); r=in.read(); } System.out.println(bao.toByteArray().toString()); return bao.toByteArray(); } public Class<?> findClass(String name){ byte[] data = null; try { data = getBytes(name); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(); return this.defineClass(name, data, 0, data.length); } public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { //loader1的父加载器为系统类加载器 MyClassLoader loader1 = new MyClassLoader("loader1"); loader1.setPath("D:/lib1/"); //loader2的父加载器为loader1 MyClassLoader loader2 = new MyClassLoader(loader1, "loader2"); loader2.setPath("D:/lib2/"); //loader3的父加载器为根类加载器 MyClassLoader loader3 = new MyClassLoader(loader2, "loader3"); loader3.setPath("D:/lib3/"); Class<?> clazz = loader3.loadClass("TestLoaderClass"); System.out.println(clazz.getClassLoader()); ClassLoader cl=loader3; } }
时间: 2024-10-16 16:44:03