美文网首页
Java 自定义 ClassLoader 实现 JVM 类加载

Java 自定义 ClassLoader 实现 JVM 类加载

作者: 田真的架构人生 | 来源:发表于2019-06-05 10:23 被阅读0次

原文:https://mp.weixin.qq.com/s/RaFIPhG1y1kmhue--MD-EQ

  • 定义需要加载的类

  • 定义类加载器

  • 编译需要加载的类文件

  • 编译自定义的类加载器并执行程序

  • 总结

定义需要加载的类
为了能够实现类加载,并展示效果,定义一个Hello类,再为其定义一个sayHello()方法,加载Hello类之后,调用它的sayHello()方法。

public class Hello {
    public static void sayHello(){
        System.out.println("Hello,I am ....");
    }
}

定义类加载器
自定义加载器,需要继承ClassLoader,并重写里面的findClass(String name) 方法。

public class MyClassLoader extends ClassLoader {
    /**
     * 重写父类方法,返回一个Class对象
     * ClassLoader中对于这个方法的注释是:
     * This method should be overridden by class loader implementations
     */
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Class clazz = null;
        String classFilename = name + ".class";
        File classFile = new File(classFilename);
        if (classFile.exists()) {
            try (FileChannel fileChannel = new FileInputStream(classFile)
                    .getChannel();) {
                MappedByteBuffer mappedByteBuffer = fileChannel
                        .map(MapMode.READ_ONLY, 0, fileChannel.size());
                byte[] b = mappedByteBuffer.array();
                clazz = defineClass(name, b, 0, b.length);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (clazz == null) {
            throw new ClassNotFoundException(name);
        }
        return clazz;
    }

    public static void main(String[] args) throws Exception{
        MyClassLoader myClassLoader = new MyClassLoader();
        Class clazz = myClassLoader.loadClass(args[0]);
        Method sayHello = clazz.getMethod("sayHello");
        sayHello.invoke(null, null);
    }
}

编译需要加载的类文件
类加载的时候加载的是字节码文件,所以需要预先把定义的Hello类编译成字节友文件。

javac Hello.java

编译自定义的类加载器并执行程序

编译代码
javac MyClassLoader.java
当然我们也可以同时编译我们所有的java源文件
javac *.java

执行成功之后,我们用下面的语句执行代码,测试是否成功,并查看结果

java MyClassLoader Hello
运行结果
Hello,I am ....

当程序按照预期显示,就证明我自定义类加载器成功了。

总结
通过上面的程序代码,简单的实现JVM的类加载过程,知道了程序运行的一点流程。但是在编写的时候有如下坑需要注意:

  • 类文件不需要指定包,否则加载的时候我们需要额外的处理,把包中的"."替换成文件系统的路径"/"。

  • 需要加载的Hello类中的反射调用的方法要用static修饰,这样invoke的时候第一个参数才可以使用null关键字代替,否则需要创建一个对应的类实例。
    官方文档中有这样一句话If the underlying method is static, then the specified obj argument is ignored. It may be null.

相关文章

  • JVM加载class文件的原理机制

    复习java知识 JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加载器是...

  • 类加载器的概述

    类加载器是JVM执行类加载机制的前提 ClassLoader的作用: ClassLoader是Java的核心组件,...

  • 深入浅出Java类加载机制

    初识ClassLoader ClassLoader类加载器在Java中的定义就是用来加载其他类到Jvm中的操作类,...

  • java中的ClassLoader

    java类加载流程 java jvm系统自带三个类加载 BootStrap ClassLoader最顶层的类加载器...

  • JAVA类加载机制

    jvm之java类加载机制和类加载器(ClassLoader)的详解java类加载机制:全盘负责、双亲委派、缓存机...

  • java类加载器

    jvm classLoader architecture :(java类加载器) i、Bootstrap Clas...

  • JVM加载class文件的原理机制

    JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加载器是一个重要的Java...

  • JVM加载class文件的原理机制

    JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加载器是一个重要的Java...

  • Java类加载源码阅读

    JVM自带加载器 启动类加载器 BootStrap ClassLoader:最顶层的类加载器,负责加载 JAVA_...

  • 笔记 classloader

    ClassLoader抽象类,主要实现:系统类加载器和自定义加载器。 ClassLoader https://ww...

网友评论

      本文标题:Java 自定义 ClassLoader 实现 JVM 类加载

      本文链接:https://www.haomeiwen.com/subject/kcdjxctx.html