動態編譯java源代碼,不生成中間文件

直接貼代碼實現

public class App2 {
    public static void main( String[] args ) throws Exception {
        String code = "public class Man {\n" +
                "\tpublic void hello(){\n" +
                "\t\tSystem.out.println(\"hello world\");\n" +
                "\t}\n" +
                "}";
        String className = "Man";

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        JavaSourceManager javaFileManager = new JavaSourceManager(compiler.getStandardFileManager(null, null, null));

        JavaSourceFromString javaFileObject = new JavaSourceFromString(className, code);
        compiler.getTask(null, javaFileManager, null, null, null, Arrays.asList(javaFileObject)).call();
        
        JavaSourceFromString myJavaFileObject = javaFileManager.getMyJavaFileObject();
        
        ClassLoader classloader = new DynamicClassLoader(myJavaFileObject);
        Class<?> clazz  = classloader.loadClass(className);
        Method method = clazz.getMethod("hello");
        method.invoke(clazz.newInstance());
    }

	public static class DynamicClassLoader extends ClassLoader {
		private byte[] bytes;

		public DynamicClassLoader(JavaSourceFromString myJavaFileObject) {
			this.bytes = myJavaFileObject.toBytes();
		}

		@Override
		protected Class<?> findClass(String name) throws ClassNotFoundException {
			return defineClass(name, bytes, 0, bytes.length);
		}
	}

    public static class JavaSourceFromString extends SimpleJavaFileObject {
        private String source;
        private ByteArrayOutputStream baos;

        public JavaSourceFromString(String name, String source) {
            super(URI.create("String:///" + name + Kind.SOURCE.extension), Kind.SOURCE);
            this.source = source;
        }

        public JavaSourceFromString(String name, Kind kind){
            super(URI.create("String:///" + name + kind.extension), kind);
            source = null;
        }

        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors){
            if(source == null){
                throw new IllegalArgumentException("source == null");
            }
            return source;
        }

        @Override
        public OutputStream openOutputStream() throws IOException {
            baos = new ByteArrayOutputStream();
            return baos;
        }

        public byte[] toBytes(){
            return baos.toByteArray();
        }
    }

    public static class JavaSourceManager extends ForwardingJavaFileManager<JavaFileManager> {
    	private JavaSourceFromString javaSourceFromString;
    	
        protected JavaSourceManager(JavaFileManager fileManager) {
            super(fileManager);
        }

        @Override
        public JavaFileObject getJavaFileForOutput(Location location, String qualifiedClassName, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
        	JavaSourceFromString javaSource = new JavaSourceFromString(qualifiedClassName, kind);
        	this.javaSourceFromString = javaSource;
            return javaSource;
        }
        
		public JavaSourceFromString getMyJavaFileObject() {
			return javaSourceFromString;
		}
    }
}

運行結果

hello world
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章