zoukankan      html  css  js  c++  java
  • 模拟IDE上的run过程

    看了一下老陈写的模仿JDK动态代理,从中取一部分单独扩展,模拟一下IDE上的run过程(不愧是老陈,去年写的东西我要现在才能理解)

    对run过程的猜想

    在点击run的过程中应该做了不少事。先编译运行run工具,执行引擎增加一个线程开始执行被加载的run工具的字节码指令;线程执行过程中将目标源码进行编译,获取ClassLoader实例对字节码进行加载,在堆上创建并初始化Class< T >对象,调用类运行时对象的静态main方法。

    模拟工具实现run过程

    import javax.tools.JavaCompiler;
    import javax.tools.StandardJavaFileManager;
    import javax.tools.ToolProvider;
    import java.lang.reflect.Method;
    
    /**
     * USER: zzzz76
     * Date: 2017/12/30
     * Time: 16:44
     */
    public class beforeRun {
        @SuppressWarnings("unchecked")
        public static void main(String[] args) {
            try {
                String fileName = args[0];
                System.err.println("run target: " + fileName);
    
                //拿到编译器
                JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
                //文件管理者
                StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
                //获取文件
                Iterable iterable = fileManager.getJavaFileObjects(fileName);
                //创建编译任务
                JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, iterable);
                //进行编译
                task.call();
                fileManager.close();
                System.err.println("************ compile successfully! ************");
    
                ClassLoader classLoader = ClassLoader.getSystemClassLoader();
                //加载目标字节码
                String className = fileName.substring(0, fileName.length() - 5);
                Class targetClass = classLoader.loadClass(className);
                //调用main方法
                Method method = targetClass.getDeclaredMethod("main", String[].class);
                method.invoke(null, (Object) new String[0]);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * USER: zzzz76
     * Date: 2017/12/30
     * Time: 17:28
     */
    public class Target {
        public static void main(String[] args) {
            System.out.println("run target!");
            Other.runOther();
        }
    }
    
    /**
     * USER: zzzz76
     * Date: 2017/12/30
     * Time: 18:14
     */
    public class Other {
        public static void runOther() {
            System.out.println("run other!");
        }
    }
    
    
    

    运行结果

    ➜  Desktop javac beforeRun.java
    ➜  Desktop java beforeRun Target.java
    run target: Target.java
    ************ compile successfully! ************
    run target!
    run other!
    



  • 相关阅读:
    查找并拷贝目录中指定文件到某个文件夹
    TPS和QPS的概念
    50道 Redis常见面试题,干货汇总
    面试题:写一个死锁示例
    MySQL聚集索引与辅助索引的区别
    Java进阶知识点:接口幂等性
    测试网络联接状况常用命令 ping 使用方法介绍
    服务路由、负载均衡和服务配置中心的基本概念
    利用堆排序和分治法求解千万级数据排序的Top K问题—百度面试
    创建Spring Boot项目时,提示 Cannot download 'https://start.spring.io'
  • 原文地址:https://www.cnblogs.com/zzzz76/p/8150862.html
Copyright © 2011-2022 走看看