美文网首页
jvm 类加载器

jvm 类加载器

作者: 程序男保姆 | 来源:发表于2021-04-27 13:09 被阅读0次

在加载类别时,每个类别加载器会先将加载类别的任务交由其parent,如果parent找不到,才由自己负责加载,如果自己也找不到,就会丢出 NoClassDefFoundError。

  • 启动类加载器 bootstarpClassLoader
    加载范围 jdk lib

  • 扩展类加载器 extensionClassLoader

  • 应用类加载器 appClassLoader
    加载范围 classPath

public class ClassLoaderStudy {

    /***
     * 在加载类别时,每个类别加载器会先将加载类别的任务交由其parent,
     * 如果parent找不到,才由自己负责加载,如果自己也找不到,就会丢出 NoClassDefFoundError。
     * @param args
     * @throws ClassNotFoundException
     */
    public static void main(String[] args) throws ClassNotFoundException {

        /***
         * 启动类加载器 bootstrapClassLoader
         *
         * 加载范围
         *
         */
        System.out.println(String.class.getClassLoader());

        /***
         * 扩展类加载器 ExtensionClassLoader
         *
         * 加载范围
         *
         */

        Class<?> driver = Class.forName("java.sql.Driver");

        System.out.println(driver.getClassLoader());


        /***
         * 应用类加载器 AppClassLoader
         *
         * 加载范围 classpath
         *
         */
        System.out.println(DatatypeException.class.getClassLoader());



        System.out.println(System.getProperty("sun.boot.class.path"));
        System.out.println(System.getProperty("java.ext.dirs"));
        System.out.println(System.getProperty("java.class.path"));
    }

}

  • 自定义类加载器(加载非classpath下的类)

public class Main {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException,
            InvocationTargetException {
            //设置加载路径
            MyClassLoader myClassLoader = new MyClassLoader("D:\\项目\\TBTX\\TX_JLM\\target\\classes\\");
            //查找指定类
            Class<?> clz = myClassLoader.findClass("com.wcn.xxx.server.XxServer");
            System.out.println(clz.getName());
            //获取指定类实例
            Object obj = clz.newInstance();
            //遍历调用方法
            Method[] methods = clz.getDeclaredMethods();
            for (Method method : methods) {
                method.invoke(obj, args);
            }
        }
    }

    class MyClassLoader extends ClassLoader {
        private String path;

        MyClassLoader(String path) {
            this.path = path;
        }

        @Override
        protected Class<?> findClass(String name) {
            File file = new File(this.path + name.replaceAll("\\.", "/") + ".class");
            byte[] bytes = new byte[0];
            try {
                //将class文件读入字节数据中
                bytes = getClassBytes(file);
            } catch (Exception ee) {
                ee.printStackTrace();
            }
            //写入内存返回Class对象
            return this.defineClass(name, bytes, 0, bytes.length);
        }

        private byte[] getClassBytes(File file) throws Exception {
            // 这里要读入.class的字节,因此要使用字节流
            FileInputStream fis = new FileInputStream(file);
            FileChannel fc = fis.getChannel();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            WritableByteChannel wbc = Channels.newChannel(baos);
            ByteBuffer by = ByteBuffer.allocate(1024);

            while (true) {
                int i = fc.read(by);
                if (i == 0 || i == -1) { break; }
                by.flip();
                wbc.write(by);
                by.clear();
            }

            fis.close();

            return baos.toByteArray();
        }

    } 

相关文章

网友评论

      本文标题:jvm 类加载器

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