以下是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; }
}

java双亲委派模型如何递归实现的更多相关文章

  1. Java 双亲委派模型

    1. Java 类加载器的分类 2. 双亲委派模型 Parents Delegration Model

  2. java双亲委派模型

    Java类加载器(ClassLoader) 双亲委派模式要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器,请注意双亲委派模式中的父子关系并非通常所说的类继承关系,而是采用组合关系来 ...

  3. java虚拟机类加载机制和双亲委派模型

    java虚拟机类加载机制:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型. 类的生命周期是从类被加载到虚拟机内存中,到卸 ...

  4. Java自定义类加载器与双亲委派模型

    其实,双亲委派模型并不复杂.自定义类加载器也不难!随便从网上搜一下就能搜出一大把结果,然后copy一下就能用.但是,如果每次想自定义类加载器就必须搜一遍别人的文章,然后复制,这样显然不行.可是自定义类 ...

  5. java类加载器和双亲委派模型

    一. 类加载器 ClassLoader即常说的类加载器,其功能是用于从Class文件加载所需的类,主要场景用于热部署.代码热替换等场景. 系统提供3种的类加载器:Bootstrap ClassLoad ...

  6. @Java类加载器及双亲委派模型

    类与类加载器 虚拟机设计团队把类加载阶段的"通过一个类的全限定名来获取此类的二进制字节流"这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这个 ...

  7. 深入理解java虚拟机(九)类加载器以及双亲委派模型

    虚拟机把类加载阶段中“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到虚拟机外部去实现,以便让程序自己决定如何去获取所需要的类.实现这个动作的代码模块称为“类加载器”. 类与类加载器 任 ...

  8. Java面试题之类加载器有哪些?什么是双亲委派模型

    类加载器有哪些: 1.启动类加载器(Bootstrap ClassLoader):这个类加载器负责将存放在<JAVA_HOME>\lib目录中的,或被-Xbootclasspath参数所指 ...

  9. java虚拟机(二)--类加载机制和双亲委派模型

    一.类的生命周期 加载(Loading).验证(Verification).准备(Preparation).解析(Resolution).初始化(Initialization).使用(Using).卸 ...

随机推荐

  1. NSFileHandle 和 NSFileManager的一些用法

    文件操作 NSFileManager 常见的NSFileManager文件的方法: -(BOOL)contentsAtPath:path 从文件中读取数据 -(BOOL)createFileAtPat ...

  2. [转载]线程间操作无效: 从不是创建控件“ListBox1”的线程访问它

    解决方法有两种: 1.Control.CheckForIllegalCrossThreadCalls = false 2.用委托解决线程安全问题

  3. SDK更新问题解决

    更新C:\WINDOWS\system32\drivers\etc\host文件百试不爽 第一步 打开SDK Manager下Tools->Options,选中“Force https://… ...

  4. orale--varchar2(5) vs varchar2(5 byte) vs varchar2(5 char)

    varchar2(5) == varchar2(5 byte)------> 'abcde' 但是中文不是5 个字符 varchar2(5 char)----> 'abcde'

  5. POJ 1797 Heavy Transportation(Dijkstra)

    http://poj.org/problem?id=1797 题意 :给出N个城市M条边,每条边都有容量值,求一条运输路线使城市1到N的运输量最大. 思路 :用dijkstra对松弛条件进行变形.解释 ...

  6. 学点PYTHON基础的东东--数据结构,算法,设计模式---单向链表

    看来看来,还是以下这个实现最优雅.. 其它的,要么NODE冗余,要么初始化丑陋... #!/usr/bin/env python # -*- coding: utf-8 -*- class Node: ...

  7. hdu 4558 剑侠情缘

    思路:dp[i][j][k]表示在点(i,j)处能量的差值为k的方案数 转移的时候把差值取相反数就实现轮流了 代码如下: #include<iostream> #include<st ...

  8. eclipse连接远程Hadoop报错,Caused by: java.io.IOException: 远程主机强迫关闭了一个现有的连接。

    eclipse连接远程Hadoop报错,Caused by: java.io.IOException: 远程主机强迫关闭了一个现有的连接.全部报错信息如下: Exception in thread & ...

  9. PLS-00103: 出现符号 ...

    Oracle存储过程: create or replace procedure update_people(in_name ), in_status in nvarchar2) as begin up ...

  10. Tableau

    http://tableau.analyticservice.net/desktop.html