Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 274|回复: 0

[Java基础知识]扩展ClassLoader定制类装载器

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-1 17:04:00 | 显示全部楼层 |阅读模式
    java的ClassLoader与Package机制介绍了ClassLoader的委派机制,它是把装载的任务传递给上级的装载器的,依次类推,直到启动类装载器(没有上级类装载器)。如果启动类装载器能够装载这个类,那么它会首先装载。如果不能,则往下传递。其实这引出一个运行时包的概念。不同装载器装载的类,即使包名相同也不能互相访问。这样保证了核心类库不被破坏。  
            本文将讲述如何扩展ClassLoader类实现一个自己的类装载器,每个Class对象都有一个引用指向装载他的ClassLoader,你可以通过public ClassLoader getClassLoader()方法得到它。为了创建自己的类装载器我们应该扩展ClassLoader类,这是一个抽象类。我们目的是从本地文件系统使用我们实现的类装载器装载一个类。
       
         
          
          
          
         
       
      
    我们创建一个FileClassLoader extends ClassLoader。我们需要覆盖ClassLoader中的
    findClass(String name)方法,这个方法通过类的名字而得到一个Class对象。
         public Class findClass(String name)
         {
             byte[] data = loadClassData(name);
             return defineClass(name, data, 0, data.length);
         }
    我们还应该提供一个方法loadClassData(String name),通过类的名称返回class文件的字节数组。然后使用ClassLoader提供的defineClass()方法我们就可以返回Class对象了。
         public byte[] loadClassData(String name)
         {
             FileInputStream fis = null;
             byte[] data = null;
             try
             {
                 fis = new FileInputStream(new File(drive + name + fileType));
                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
                 int ch = 0;
                 while ((ch = fis.read()) != -1)
                 {
                     baos.write(ch);
                   
                 }
                 data = baos.toByteArray();
             } catch (IOException e)
             {
                 e.printStackTrace();
             }
             
             return data;
         }
    这里我们是从D盘装载一个类。      下面我们提供一个类public class MyApp{},类中没有定义任何方法和变量,下面我们编译MyApp.java得到MyApp.class,然后把文件放在D盘的根目录。为了证明MyApp.class是被我们定义的classloader装载的,我们在FileClassLoader的main()方法中打印出装载MyApp.class的类装载器的名称。
         public static void main(String[] args) throws Exception
         {
             FileClassLoader loader = new FileClassLoader();
             Class objClass = loader.loadClass("MyApp", true);         Object obj = objClass.newInstance();
             System.out.println(objClass.getName());
             System.out.println(objClass.getClassLoader());
          
                  
          }
    编译FileClassLoader
    javac FileClassLoader.java  然后运行java FileClassLoader 可以看到输出结果为
    MyApp
    FileClassLoader@1a5ab41
    如果你把MyApp.class放入到你程序的所在目录会出现什么情况呢?读者自己实践一下吧!下面给出FileClassLoader的源代码。
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException; public class FileClassLoader extends ClassLoader
    {
         public static final String drive = "d:/";
         public static final String fileType = ".class";
      
         public FileClassLoader() {
             super();
      
         }
      
         public FileClassLoader(ClassLoader arg0) {
             super(arg0);
         }
      
         public Class findClass(String name)
         {
             byte[] data = loadClassData(name);
             return defineClass(name, data, 0, data.length);
         }
      
         public byte[] loadClassData(String name)
         {
             FileInputStream fis = null;
             byte[] data = null;
             try
             {
                 fis = new FileInputStream(new File(drive + name + fileType));
                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
                 int ch = 0;
                 while ((ch = fis.read()) != -1)
                 {
                     baos.write(ch);
                   
                 }
                 data = baos.toByteArray();
             } catch (IOException e)
             {
                 e.printStackTrace();
             }
             
             return data;
         }
         
      
         public static void main(String[] args) throws Exception
         {
             FileClassLoader loader = new FileClassLoader();
             Class objClass = loader.loadClass("MyApp", true);         Object obj = objClass.newInstance();
             System.out.println(objClass.getName());
             System.out.println(objClass.getClassLoader());
          
                  
          }
    }
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-3 21:53 , Processed in 0.434039 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表