您的位置:首页 > 职场人生

黑马程序员-(高新技术)类加载器

2015-05-09 13:40 369 查看
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------


类加载器概述:

java中默认的类加载器有三个

BootStrp------>JRE/lib/rt.jar
ExtClassLoader---------->JRE/lib/ext/*.jar

AppClassLoader---------->CLASSPATH指定的所有jar或目录。 

这三个类加载器有继承关系:

AppClassLoader extends ExtClassLoader
extends BootStrp 

并且其实类加载器也是一个java文件,也需要被别的类加载器所加载那么,最父类的类加载器是由谁加载的呢

BootStrp是直接写在jvm虚拟机中的一段程序,是由c++代码写的(感谢张孝祥老师,谢谢)


类加载器的委托机制:

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

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

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

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

类加载器加载类时委托给他的上一级父类加载器,直到最顶端,由它来加载。若在最顶端的那个加载器没有加载到了类再返回到其子类加载器,再由它来执行加载,以此类推,当返回到发起者类加载器时,如果还没找到就抛出异常。

为什么委托机制要一步步抛给父类?

集中管理,如果我们写了几个类加载器,都去加载某个类,那么内存中就有多份这个类的字节码

能不能自己写一个类叫java.lang.System?

为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸优先,也就是使用的永远是爸爸的(系统的)System类,而不是我们写的System类.


类加载器示范

继承ClassLoader,覆盖findClass方法

package cn.itheima.ClassLoader;

import java.io.ByteArrayOutputStream;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

public class MyClassLoader extends ClassLoader {

private String dir;

public MyClassLoader() {
super();
}

public MyClassLoader(String dir) {
super();
this.dir = dir;
}

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

String src = args[0];
String dest = args[1];

FileInputStream fileIn = new FileInputStream(src);

String destName = src.substring(src.lastIndexOf('\\')+1);
dest = dest+"\\"+destName;
FileOutputStream fileOut = new FileOutputStream(dest);
copy(fileIn,fileOut);
fileIn.close();
fileOut.close();
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {

//通过裁剪得到一个class文件的路径
String dirPath = dir+"\\"+name.substring(name.indexOf('.')+1)+".class";

try {
FileInputStream fileIn = new FileInputStream(dirPath);
ByteArrayOutputStream buyOut = new ByteArrayOutputStream();
copy(fileIn, buyOut);
fileIn.close();//将字节反转
byte[] buy = buyOut.toByteArray();//装到数组里面

return defineClass(buy, 0, buy.length);//将字节转成class对象返回

} catch (Exception e) {

e.printStackTrace();
}

return super.findClass(name);
}

public static void copy(InputStream in, OutputStream out) throws Exception{

int b = -1;
while((b=in.read()) != -1){

out.write(b ^ 0xff);
}
}

}

package cn.itheima.ClassLoader;

public class Demo {

@Override
public String toString(){

return "hello,itcast";


}

package cn.itheima.ClassLoader;

public class ClassLoaderTest {

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

Class clazz = new MyClassLoader("copylib").loadClass("Demo");//调用指定类加载器
Object demo = (Object)clazz.newInstance();//将加载到的烂逼类变成他的父类
System.out.println(demo.toString());
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: