ClassLoader类加载器

本文介绍了Java中ClassLoader类加载器的基础概念,包括系统类加载器的获取方法,自定义ClassLoader如何在类加载顺序中的应用,以及如何通过自定义ClassLoader加载本地或远程资源。实例演示了如何创建并使用自定义TClassLoader加载未打包的Message类。
摘要由CSDN通过智能技术生成

ClassLoader类加载器

1、ClassLoader类加载器简介

在Java语言里面提供有一个系统的环境变量:CLASSPATH,这个环境属性的作用主要是在JVM进程启动的时候进行类加载路径的定义,在JVM里面可以根据类加载器而后进行指定路径中类的加载,也就是说找到了类的加载器就意味着找到了类的来源

系统类加载器

如果说现在要想获得类的加载器,那么一定要通过ClassLoader来获取,而要想获取ClassLoader_类的对象,则必须利用Class类(反射的根源)实现,方法:

  • public ClassLoader getClassLoader()

当获取了ClassLoader之后还可以继续获取其父类的ClassLoader对象

  • public final ClassLoader getParent()

类加载器

public class JavaDemo {
   public static void main(String[] args) throws Exception {
      Class<Person> aClass = Person.class;
      System.out.println(aClass.getClassLoader());
      System.out.println(aClass.getClassLoader().getParent());
      System.out.println(aClass.getClassLoader().getParent().getParent());
   }
}
//jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
//jdk.internal.loader.ClassLoaders$PlatformClassLoader@7c30a502
//null

当你获得了类加载器之后就可以利用类加载器来实现类的反射加载处理。

2、自定义ClassLoader处理类

自定义类加载器的加载顺序是在所有系统类加载的最后加载的

系统类中的类加载器都是根据CLASSPATH路径进行类加载的,而如果有了自定义加载器,就可以由开发者任意指派

1、随意编写一个程序类,并将此类保存到磁盘上

public class Message {
   public void send(){
      System.out.println("发送消息");
   }
}

2、将此类拷贝到磁盘上进行编译处理,并且不打包:javac Message.java

此时并没有进行打包处理,所以这个类无法通过CLASSPATH正常加载

3、自定义一个类加载器,并且继承自ClassLoader类。在 ClassLoader类里面为用户提供有一个字节转换为类结构的方法

  • protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError
public class TClassLoader extends ClassLoader{
   
   private static final String MESSAGE_CLASS_PATH = "E:" + File.separator + "Message.class";
   
   /**
    * 进行指定类的加载
    * @param className 类的完整名称“bao.类”
    * @return 返回一个指定类的Class对象
    * @throws Exception 如果类文件不存在则无法加载
    */
   public Class<?> loadDate(String className) throws Exception{
      byte [] data = this.loadClassData();    //读取二进制文件
      if (data != null) { //读取到了
         return super.defineClass(className , data , 0 , data.length);
      }
      return  null;
   }
   
   /**
    * 通过文件进行类的加载
    */
   private byte [] loadClassData() throws Exception{
      InputStream input = null;
      //将数据加载到内存之中
      ByteArrayOutputStream bos = null;
      byte data [] = null;
      try {
         input = new FileInputStream(new File(MESSAGE_CLASS_PATH));
         input.transferTo(bos);  //读取数据
         data =  bos.toByteArray();  //将所有读取到的字节数据取出
      } catch (Exception e){
         e.printStackTrace();
      } finally {
         if (input != null) {
            input.close();
         }
         if (bos != null) {
            bos.close();
         }
      }
      return data;
   }
}

4、编写测试类经实现加载控制

public class JavaDemo {
   public static void main(String[] args) throws Exception {
      TClassLoader classLoader = new TClassLoader();
      Class<?> aClass = classLoader.loadDate("com.xialuote.domain.Message");
      Object obj = aClass.getDeclaredConstructor().newInstance();
      Method method = aClass.getDeclaredMethod("send");
      method.invoke(obj);
   }
}

如果在以后结合到网络程序开发的话,就可以通过一个远程的服务器来确定类的功能。

如果自定义的加载类的名字与系统类名字一致,则不会被加载

下一篇:反射与代理设计模式

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MyRedScarf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值