您的位置:首页 > 编程语言 > Java开发

JAVA动态编译

2016-06-24 10:56 323 查看
今天在弄游戏的GM模块,大部分gm命令很简单,只是单纯改变某些参数的值。

 

突然,想到一个问题,就是在线上运行服务器时,假如我要改变某个参数的值,有

 

没有办法呢?通过查找资料后,发现jdk竟然也提供了动态编译的工具。因此,我

 

们可以让java变成一个脚本语言。我发送一个类的代码到服务端,动态编译后,利

 

用反射来执行。代码很简单,我从网上找了一个例子简单改装一下

import java.io.IOException;  

import java.lang.reflect.Method;  

import java.net.URI;  

import java.net.URL;  

import java.net.URLClassLoader;  

import java.util.Arrays;  

import java.util.Scanner;  

  

import javax.tools.JavaCompiler;  

import javax.tools.JavaCompiler.CompilationTask;  

import javax.tools.JavaFileObject;  

import javax.tools.SimpleJavaFileObject;  

import javax.tools.ToolProvider;  

  

public class CompileTest {  

  

    public static final String CLASS_CONTENT = "public class HelloWorld{public static void run(){##;}}";  

  

    public static void main(String[] args) throws Exception {  

        Scanner scanner =new Scanner(System.in);  

        String code = scanner.nextLine();  

        code = CLASS_CONTENT.replace("##", code);  

          

        //获取编译器.注意,运行时需要jdk,单纯的jre没有编译器  

        JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();  

        JavaFileObject fileObject = new JavaStringObject("HelloWorld",  

                code);  

        //编译过程  

        CompilationTask task = javaCompiler.getTask(null, null, null,  

                Arrays.asList("-d", "./bin"), null, Arrays.asList(fileObject));  

        if (!task.call()) {  

            System.out.println("编译失败!");  

        } else {  

            System.out.println("编译成功!");  

  

            //成功以后,就利用发射来执行这个类了  

            URL[] urls = new URL[] { new URL("file:/" + "./bin/") };  

            URLClassLoader classLoader = new URLClassLoader(urls);  

            Class<?> clazz = classLoader.loadClass("HelloWorld");  

            Method method = clazz.getDeclaredMethod("run");  

            method.invoke(clazz.newInstance());  

        }  

  

    }  

  

    static class JavaStringObject extends SimpleJavaFileObject {  

        private String code;  

  

        public JavaStringObject(String name, String code) {  

            super(URI.create(name + ".java"), Kind.SOURCE);  

            this.code = code;  

        }  

  

        @Override  

        public CharSequence getCharContent(boolean ignoreEncodingErrors)  

                throws IOException {  

            return code;  

        }  

    }  



运行代码

输入一条java语句,例如:System.out.println("hello,美女!"); 

 

总结

利用java的这个小特性,我们可以做一些有益的事情,很多时候不需要为了更改某些参数而停服了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java