zoukankan      html  css  js  c++  java
  • java双亲委派模型如何递归实现

    以下是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; } }
  • 相关阅读:
    递归打印99乘法表
    递归对一个数组求和
    在控制台打印出99乘法表
    ie9以下浏览器不兼容placeholder的解决方案
    二列布局 左边固定宽度 右边响应
    Scala并发编程实战初体验及其在Spark源码中的应用解析之Scala学习笔记-56
    Scala中隐式转换内幕操作规则揭秘、最佳实践及其在Spark中的应用源码解析之Scala学习笔记-55
    Scala中隐式对象代码实战详解之Scala学习笔记-54
    Scala中隐式类代码实战详解之Scala学习笔记-53
    Scala中上下文界定内幕中的隐式参数与隐式参数的实战详解及其在Spark中的应用源码解析之Scala学习笔记-52
  • 原文地址:https://www.cnblogs.com/hansongjiang/p/4242437.html
Copyright © 2011-2022 走看看