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

------- <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());
}


}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值