Java中怎么自定义一个类加载器
创始人
2024-12-22 01:02:22
0次

一 点睛

1 ClassLoader类有如下两个关键方法:

loadClass(String name, boolean resolve):该方法为ClassLoader的入口点,根据指定的二进制名称来加载类,系统就是调用ClassLoader的该方法来获取指定类对应的Class对象。

findClass(String name):根据二进制名称来查找类。

如果需要实现自定义的ClassLoader,可以通过重写以上两个方法来实现,当然我们推荐重写findClass()方法,而不是重写loadClass()方法。

2 自定义类加载器常用功能

执行代码前自动验证数字签名。

根据用户提供的密码解密代码,从而可以实现代码混淆器来避免反编译class文件。

根据用户需求来动态地加载类。

根据应用需求把其他数据以字节码的形式加载到应用中。

二 实战

1 CompileClassLoader.java

import java.io.*;import java.lang.reflect.*;public class CompileClassLoader extends ClassLoader{  // 读取一个文件的内容  private byte[] getBytes(String filename)     throws IOException  {   File file = new File(filename);   long len = file.length();   byte[] raw = new byte[(int)len];   try(      FileInputStream fin = new FileInputStream(file))   {     // 一次读取class文件的全部二进制数据     int r = fin.read(raw);     if(r != len)      throw new IOException("无法读取全部文件:"         + r + " != " + len);     return raw;   }  }  // 定义编译指定Java文件的方法  private boolean compile(String javaFile)     throws IOException  {   System.out.println("CompileClassLoader:正在编译 "      + javaFile + "...");   // 调用系统的javac命令   Process p = Runtime.getRuntime().exec("javac " + javaFile);   try   {     // 其他线程都等待这个线程完成     p.waitFor();   }   catch(InterruptedException ie)   {     System.out.println(ie);   }   // 获取javac线程的退出值   int ret = p.exitValue();   // 返回编译是否成功   return ret == 0;  }  // 重写ClassLoader的findClass方法  protected Class findClass(String name)     throws ClassNotFoundException  {   Class clazz = null;   // 将包路径中的点(.)替换成斜线(/)。   String fileStub = name.replace("." , "/");   String javaFilename = fileStub + ".java";   String classFilename = fileStub + ".class";   File javaFile = new File(javaFilename);   File classFile = new File(classFilename);   // 当指定Java源文件存在,且class文件不存在、或者Java源文件   // 的修改时间比class文件修改时间更晚,重新编译   if(javaFile.exists() && (!classFile.exists()      || javaFile.lastModified() > classFile.lastModified()))   {     try     {      // 如果编译失败,或者该Class文件不存在      if(!compile(javaFilename) || !classFile.exists())      {        throw new ClassNotFoundException(           "ClassNotFoundExcetpion:" + javaFilename);      }     }     catch (IOException ex)     {      ex.printStackTrace();     }   }   // 如果class文件存在,系统负责将该文件转换成Class对象   if (classFile.exists())   {     try     {      // 将class文件的二进制数据读入数组      byte[] raw = getBytes(classFilename);      // 调用ClassLoader的defineClass方法将二进制数据转换成Class对象      clazz = defineClass(name,raw,0,raw.length);     }     catch(IOException ie)     {      ie.printStackTrace();     }   }   // 如果clazz为null,表明加载失败,则抛出异常   if(clazz == null)   {     throw new ClassNotFoundException(name);   }   return clazz;  }  // 定义一个主方法  public static void main(String[] args) throws Exception  {   // 如果运行该程序时没有参数,即没有目标类   if (args.length < 1)   {     System.out.println("缺少目标类,请按如下格式运行Java源文件:");     System.out.println("java CompileClassLoader ClassName");   }   // 第一个参数是需要运行的类   String progClass = args[0];   // 剩下的参数将作为运行目标类时的参数,   // 将这些参数复制到一个新数组中   String[] progArgs = new String[args.length-1];   System.arraycopy(args , 1 , progArgs      , 0 , progArgs.length);   CompileClassLoader ccl = new CompileClassLoader();   // 加载需要运行的类   Class clazz = ccl.loadClass(progClass);   // 获取需要运行的类的主方法   Method main = clazz.getMethod("main" , (new String[0]).getClass());   Object[] argsArray = {progArgs};   main.invoke(null,argsArray);  }}

2 Hello.java

public class Hello{  public static void main(String[] args)  {   for (String arg : args)   {     System.out.println("运行Hello的参数:" + arg);   }  }}

3 运行

E:\Java\疯狂java讲义\codes\18\18.2>java CompileClassLoader Hello 

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...