黑马程序员_类加载器

------- 物联云培训java培训、期待与您交流! ----------  

类加载器

类加载器分为三种:BootStrap、ExtClassLoader、AppClassLoader。

类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成java.lang.Class类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的 newInstance()方法就可以创建出该类的一个对象。

    自定义类加载器要实现java.lang.ClassLoader

java.lang.ClassLoader类的基本职责就是根据一个指定的类的名称,找到或者生成其对应的字节代码,然后从这些字节代码中定义出一个 Java 类,即 java.lang.Class类的一个实例。除此之外,ClassLoader还负责加载 Java 应用所需的资源,如图像文件和配置文件等。不过本文只讨论其加载类的功能。为了完成加载类的这个职责,ClassLoader提供了一系列的方法

类加载器的委托机制:

每个ClassLoader本身只能分别加载特定位置和目录中的类,但它们可以委托其他的类装载器去加载类,这就是类加载器的委托模式。类装载器一级级委托到BootStrap类加载器,当BootStrap无法加载当前所要加载的类时,然后才一级级回退到子孙类装载器去进行真正的加载。当回退到最初的类装载器时,如果它自己也不能完成类的装载,那就应报告ClassNotFoundException异常。也就是说,当类加载器加载类时,它会先上一级加载器,让上一级加载器加载类,而上一级也会做同样的事,知道最顶层。如果顶层加载不了,就会给下一层,下一层如果加载不了继续下一层,直到发起者停止,如果没找到报ClassNotFoundException异常


自定义类加载器并实现加密解密:

代码如下:

publicclassMyClassLoaderextendsClassLoader{
    publicstaticvoid main(String[] args) throws Exception {
        String srcPath=args[0];
        String desDir=args[1];
        FileInputStreamfileIn=newFileInputStream(srcPath);
        String desPath=desDir+"\\"+srcPath.substring(srcPath.lastIndexOf('\\')+1);
        FileOutputStreamfileOut=newFileOutputStream(desPath);
        copyfile(fileIn,fileOut);
        fileIn.close();
        fileOut.close();
    }
    publicstaticvoidcopyfile(InputStreamin,OutputStream out) throws Exception
    {
        inti=-1;
            while((i=in.read())!=-1)
            {
                out.write(i^0xff);
            }
    }
    private String desfiles;
 
@Override
protectedClassfindClass(String name) throwsClassNotFoundException {
    String file="javalib"+"//"+name+".class";
    try {
        FileInputStream In=newFileInputStream(file);
        ByteArrayOutputStream by=newByteArrayOutputStream();
        copyfile(In,by);
        In.close();
        byte[]bytes=by.toByteArray();
        returndefineClass(bytes,0,bytes.length);
    } catch(Exception e) {
        e.printStackTrace();
    }
returnnull;   
}
publicMyClassLoader()
{
    }
publicMyClassLoader(String desfiles)
{
    this.desfiles=desfiles;
    }
}
//测试类
publicclassClassLoaderTest {
    publicstaticvoid main(String[] args) throwsClassNotFoundException, InstantiationException, IllegalAccessException {
        Classcalzz=
newMyClassLoader("javalib").loadClass("ClassLoaderAttachment");
            Date d=(Date) calzz.newInstance();
        System.out.println(d);
    }
}

总结:自定义类加载器必须继承java.lang.ClassLoader

      要覆盖findClass方法,不用覆盖loadClass方法。

原因是:为了保留原来的类加载器委托机制。

加载器的委托机制有利也有弊,

利:便于类的同一管理,一个类只会出现一份字节码,节省内存。

弊:增加CPU负担,运行速率较慢。

总体来说类加载器的委托机制利大于弊。


------- 物联云培训java培训、期待与您交流! ----------  

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值