美文网首页
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