l 当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?

1.首先当前线程的类加载器去加载线程中的第一个类。

2.如果类A中引用了类B,Java虚拟机将使用加载类A的类装载器来加载类B。

3.还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。

l 每个类加载器加载类时,又先委托给其上级类加载器。

1.当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛ClassNotFoundException,不是再去找发起者类加载器的儿子,因为没有getChild方法,即使有,那有多个儿子,找哪一个呢?

2.对着类加载器的层次结构图和委托加载原理,解释先前将ClassLoaderTest输出成jre/lib/ext目录下的itcast.jar包中后,运行结果为ExtClassLoader的原因。

每个ClassLoader本身只能分别加载特定位置和目录中的类,但它们可以委托其他的类装载器去加载类,这就是类加载器的委托模式。类装载器一级级委托到BootStrap类加载器,当BootStrap无法加载当前所要加载的类时,然后才一级级回退到子孙类装载器去进行真正的加载。当回退到最初的类装载器时,如果它自己也不能完成类的装载,那就应报告ClassNotFoundException异常。

有一道面试,能不能自己写个类叫java.lang.System,为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸们优先,也就是总是使用爸爸们能找到的类,这样总是使用java系统提供的System。

把先前编写的类加入到jdk的rt.jar中,会有怎样的效果呢?不行!!!看来是不能随意将自己的class文件加入进rt.jar文件中的。

编写自己的类加载器(需要再仔细看一遍,不是太懂)

知识讲解:

自定义的类加载器的必须继承ClassLoader

loadClass方法(直接继承,省去委托机制的编写)与findClass方法(覆盖这个就行了)

defineClass方法

编程步骤:

编写一个对文件内容进行简单加密的程序。

编写了一个自己的类装载器,可实现对加密过的类进行装载和解密。

编写一个程序调用类加载器加载类,在源程序中不能用该类名定义引用变量,因为编译器无法识别这个类。程序中可以除了使用ClassLoader.load方法之外,还可以使用设置线程的上下文类加载器或者系统类加载器,然后再使用Class.forName。

实验步骤:

对不带包名的class文件进行加密,加密结果存放到另外一个目录,例如: java MyClassLoader MyTest.class F:\itcast

运行加载类的程序,结果能够被正常加载,但打印出来的类装载器名称为AppClassLoader:java MyClassLoader MyTest F:\itcast

用加密后的类文件替换CLASSPATH环境下的类文件,再执行上一步操作就出问题了,错误说明是AppClassLoader类装载器装载失败。

删除CLASSPATH环境下的类文件,再执行上一步操作就没问题了。

import java.io.*;

import java.lang.reflect.*;

public class MyClassLoader extends ClassLoader

{

private String path = null;

public MyClassLoader(String path) throws Exception//检查文件是否存在

{

File f = new File(path);

if(!f.isDirectory())

{

throw new RuntimeException(path + " is not a directory");

}

this.path = path;

}

public Class findClass(String name) //throws Exception //为什么不能抛出

{

try

{

File f = new File(path,name.substring(name.lastIndexOf('.')+1) + ".class");

FileInputStream fis = new FileInputStream(f);

ByteArrayOutputStream bos = new ByteArrayOutputStream();

cypher(fis,bos);

byte [] buf = bos.toByteArray();

fis.close();

bos.close();

return defineClass(name,buf,0,buf.length);

}catch(Exception e)

{

throw new ClassNotFoundException(name + " is not found!");

}

return null;

}

public static void cypher(InputStream istream,OutputStream ostream) throws Exception

{

//下面这段代码可能遇到255的字节,当成byte就成了-1

/*byte b = 0;

while((b = (byte)istream.read()) != -1)

{

ostream.write(b ^ 0xff);

}*/

int b = 0;

while((b = istream.read()) != -1)

{

ostream.write(((byte)b) ^ 0xff);

}

}

public static void main(String [] args) throws Exception

{

//下面省略了错误检查

if(!args[0].endsWith("class"))

{

ClassLoader loader = new MyClassLoader(args[1]);

Class cls = loader.loadClass(args[0]);

/*

让自定义类继承Date类

System.out.println(cls.getClassLoader().getClass().getName());

java.util.Date d = (java.util.Date)cls.newInstance();

System.out.println(d.toString());

*/

//Method m = cls.getMethod("test",null);//在jdk1.5中报警告,为什么?

Method m = cls.getMethod("test");

//m.invoke(cls.newInstance(),null);

m.invoke(cls.newInstance());

//((Test)cls.newInstance()).test();

return;

}

else

{

FileInputStream fis = new FileInputStream(args[0]);

File f = new File(args[1], new File(args[0]).getName());//不用检查目录最后是否有目录分割符

FileOutputStream fos = new FileOutputStream(f);

cypher(fis,fos);

fis.close();

fos.close();

}

}

}

//类加载器不能加载这种非public的类

/*

Exception in thread "main" java.lang.IllegalAccessException: Class MyClassLoader

can not access a member of class MyTest with modifiers ""

*/

/*

class MyTest

{

public void test()

{

System.out.println("hello,www.it315.org");

}

}

*/

java 类加载器的委托机制的更多相关文章

  1. java类加载器及其委托机制

    1.什么是类加载器,类加载器父子结构.BootStrap-->ExtClassLoader-->AppClassLoader,级别依次降低 2.类加载器之间的父子关系和管辖范围 3.类加载 ...

  2. java类加载器-系统类加载器

    系统类加载器 系统类加载器可能都耳详能熟,但是为了完整点,还是先简单的说说系统的类加载器吧. public class Test { public static void main(String[] ...

  3. Java 类加载器(转)

    java虚拟机中可以安装多个类加载,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap(内嵌在java虚拟机中由C++编写),ExtClassLoader,AppClassLoa ...

  4. Java基础-类加载机制与自定义类Java类加载器(ClassLoader)

    Java基础-类加载机制与自定义类Java类加载器(ClassLoader) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 关于类加载器的概念和分类我就不再废话了,因为我在之前的笔 ...

  5. java笔记--理解java类加载器以及ClassLoader类

    类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...

  6. java类加载器深入研究

    看了下面几篇关于类的加载器的文章,豁然开朗.猛击下面的地址开始看吧. Java类加载原理解析      深入探讨 Java 类加载器 分析BootstrapClassLoader/ExtClassLo ...

  7. 深入探讨 Java 类加载器

    转自:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 类加载器(class loader)是 Java™中的一个很重要的概念.类 ...

  8. JAVA 类加载器 第14节

    JAVA 类加载器 第14节 今天我们将类加载机制5个阶段中的第一个阶段,加载,又叫做装载.为了阅读好区分,以下都叫做装载. 装载的第一步就是要获得二进制的字节流,它可以从读.class文件获得,也可 ...

  9. 深入探讨 Java 类加载器[转]

    原文地址:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html 类加载器(class loader)是 Java™ ...

随机推荐

  1. 【风马一族_php】NO5_php基础知识_数组

    原文来自:http://www.cnblogs.com/sows/p/6032570.html (博客园的)风马一族 侵犯版本,后果自负 回顾 匿名函数 定义: 变量 = function [参数列表 ...

  2. 【机器学习PAI实战】—— 玩转人工智能之综述

    摘要: 基于人工智能火热的大背景下,通过阿里云的机器学习平台PAI在真实场景中的应用,详细阐述相关算法及使用方法,力求能够让读者读后能够马上动手利用PAI搭建属于自己的机器学习实用方案,真正利用PAI ...

  3. 51nod1040 矩阵相乘结果的判断

    给出三个N*N的矩阵A, B, C,问A * B是否等于C?Input第1行,1个数N.(0 <= N <= 500)第2 - N + 1行:每行N个数,对应矩阵A的元素.(0 <= ...

  4. KNN最近邻算法

    算法概述 K最近邻(K-Nearest Neighbor,KNN)算法,是著名的模式识别统计学方法,在机器学习分类算法中占有相当大的地位.它是一个理论上比较成熟的方法.既是最简单的机器学习算法之一,也 ...

  5. oracle怎么捕获用户登录信息,如SID,IP地址等

    可以利用登录触发器,如 CREATE OR REPLACE TRIGGER tr_login_record AFTER logon ON DATABASE DECLARE miUserSid NUMB ...

  6. python 文本文件的读取

  7. C++运行时类型识别

    通过运行时类型识别(RTTI),程序能够使用基类的指针或引用来检索这些指针或引用所指对象的实际派生类型. 通过下面两个操作符提供 RTTI: 1. typeid 操作符,返回指针或引用所指对象的实际类 ...

  8. GIT 公钥配置

    1.下载git 2.ssh-keygen -t rsa -C "xxx@xxx.com" 3.cd ~/.ssh 4.ls 5.cat id_rsa.pub 或者C:\User\x ...

  9. XAML 很少人知道的科技 - walterlv

    原文:XAML 很少人知道的科技 - walterlv XAML 很少人知道的科技 发布于 2019-04-30 02:30 更新于 2019-04-30 11:08 本文介绍不那么常见的 XAML ...

  10. SDUT-1479_数据结构实验之栈与队列九:行编辑器

    数据结构实验之栈与队列九:行编辑器 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 一个简单的行编辑程序的功能是:接受用 ...