类加载器(classloader):


类加载器(classloader):

 java类加载器感觉好难,不是很好理解,只能去理解他最基础的部分。

 1.什么是类加载器

  根据名字大慨知道他是加载类的工具,就是把一个java类加载到java虚拟机中。java源文件通过编译,生产字节码文件,类加载器就是负责读取字节码文件的,并装换成java.lang.Class类的实例,每个这样的实例表示一个java类。通过实例的newInstance方法创建该类的对象。

2.加载器中种类(主要有3种):

1.跟类加载器(Bootstrap):它用来加载 Java 的核心库,是用c语言来编写的,并不是由Java代码编写的,此类加载器是所有类的祖宗。并不继承自    java.lang.ClassLoader

  2.扩展类加载器(ExtClassLoader):它用来加载 Java 的扩展库(就是额外的jar比如我们自己写的Java类打成jar就可以放在这里)。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。

  3.系统类加载器(AppClassLoader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过ClassLoader.getSystemClassLoader()来获取它。

(注:跟加载器不是有java编写的)

3. 类加载器的委托机制:

当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
首先当前线程的类加载器去加载线程中的第一个类。
如果类A中引用了类B,Java虚拟机将使用加载类A的类装载器来加载类B。 
还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。
每个类加载器加载类时,又先委托给其上级类加载器。自己先不加载,这样如果当父加载器,找到要加载的类就会直接返回会给它的子加载器,如果父类没有找到,它就会让子去找,若是找到就直接返回给它自己,找不到就直接抛出一个ClassNotFoundException。
(总结就一句话:找爸爸)

4.怎么得到一个类的类加载器:
       类名.class.getClassLoader().getClass().getname();获取类加载器名称。

5.自定义一个类加载器。
       基础知识:
 1.自定义一个类加载器必须继承classLoader。
 2.明白loaderclass方法(找父亲)和findclass方法。(需要覆盖)
 3.明白defilneclass方法。(把一个数组变成一个class字节码)
                 4.运用了模版方法设计模式。

代码:

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
//定义一个类继承Classloader
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);
//加密
  encrypt(fis,fos);
 
 fis.close();
 fos.close();
 }
 //定义一个文件加密器
 public static void encrypt(InputStream is, OutputStream os) throws Exception
 {
     int b = -1;
    while((b=is.read())!= -1)
  {//加密^ 0xff
    os.write((byte)b ^ 0xff);
  }
 }
 
 
 //复写findClass
 //定义一个从那加载的目录变量
 private String classDir;
 
 public MyClassLoader() {}
 public MyClassLoader(String classDir) {
      this.classDir = classDir;
 }

 @Override
 protected Class<?> findClass(String name) throws ClassNotFoundException {
  // 定义加载器从哪个目录下读
  String classFileName = classDir +"\\"+name+".class";
  try {//定义输入流关联要读取的目录
   FileInputStream fis = new FileInputStream(classFileName);
   ByteArrayOutputStream baos = new ByteArrayOutputStream();
   //解密
   encrypt(fis,baos); 
   //转成字节
   byte[] bytes = baos.toByteArray();
   //将字节转成字节码文件。
   return defineClass(bytes, 0, bytes.length);
  } catch (FileNotFoundException e) {
   //
   e.printStackTrace();
  } catch (Exception ex) {
   ex.printStackTrace();
  }
  //返回findClass
  return super.findClass(name);
 }

类加载器是个难点,要多写多用才能好的理解。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值