黑马程序员-类加载器(class loader)

------- android培训java培训、期待与您交流! ----------

一:类加载器的概念

   类加载器用来加载 Java 类到 JVM中。

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

 

二:系统中间的关系及它们之间的管辖图

注:Boot是特殊的类加载器  它不是类  当用户想得到它并且打印它的名字会得到NULL

ClassLoader loader = ClassLoaderTest.class.getClassLoader(); 
while (loader != null) {
System.out.println(loader.getClass().getName());
loader = loader.getParent();
}
System.out.println(loader);
结果

   
   
 
 
 
三:类加载器的委托机制       

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

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

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

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

2>每个类加载器加载类时,又先委托给其上级类加载器.                    

当所有祖宗类加载器没有加载到类,回到发起者类加载器,如果还加载不了,则抛出ClassNotFoundException异常,它不会 去找发起者类加载器的儿子,因为没有getChild()方法,即使有,有那么多的儿子交给那一个呢?所以干错就不叫给儿子处理了.     

四:建立自己的类加载器(用来加密文件,解密文件      

首先加密:   

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

        String srcPath = args[0];

        String destDir = args[1];

        FileInputStream fis = new FileInputStream(srcPath);

        String destFileName = srcPath.substring(srcPath.lastIndexOf('\\')+1);

        String destPath = destDir + "\\" + destFileName;

        FileOutputStream fos = new FileOutputStream(destPath);

        cypher(fis,fos);

        fis.close();

        fos.close();

    }

 

    /**

     * 加密方法,同时也是解密方法

     */

    private static void cypher(InputStream ips ,OutputStream ops) throws Exception{

        int b = -1;

        while((b=ips.read())!=-1){

            ops.write(b ^ 0xff);//通过异或来加密文件        }

    }

下面为需要加密的类

public class ClassLoaderAttachment extends Date { //为什么要继承Date待会再说? 
    public String toString(){
        return "hello,itcast";
    } 
}


 

自定义进行解密的类加载器

public class MyClassLoader extends ClassLoader{ 

 

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

        String srcPath = args[0];

        String destDir = args[1];

        FileInputStream fis = new FileInputStream(srcPath);

        String destFileName = srcPath.substring(srcPath.lastIndexOf('\\')+1);

        String destPath = destDir + "\\" + destFileName;

        FileOutputStream fos = new FileOutputStream(destPath);

        cypher(fis,fos);

        fis.close();

        fos.close();

    }

 

    /**

     * 加密方法,同时也是解密方法

     */

    private static void cypher(InputStream ips ,OutputStream ops) throws Exception{

        int b = -1;

        while((b=ips.read())!=-1){

            ops.write(b ^ 0xff);//异或一次为加密 第二次为解密        }

    }

 

    private String classDir;

 

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

        String classFileName = classDir + "\\" + name.substring(name.lastIndexOf('.')+1) + ".class";

        try {

            FileInputStream fis = new FileInputStream(classFileName);

            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            cypher(fis,bos);

            fis.close();

            System.out.println("aaa");

            byte[] bytes = bos.toByteArray();

            return defineClass(bytes, 0, bytes.length);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return null;

    }

 

    public MyClassLoader(){

    }

 

    public MyClassLoader(String classDir){

        this.classDir = classDir;

    }

}

测试运行代码:

 

        Class clazz = new MyClassLoader("myClass").loadClass("ClassLoaderAttachment"); 

        /*此处不能在使用ClassLoaderAttachment因为一旦用了之后,

        系统的类加载器就会去加载,但是找不到因为运行时才有生成的此类,导致失败,所以该类就继承了Date类了.*/

        Date date = (Date)clazz.newInstance();

        System.out.println(date);

结果为

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值