java 内存编译_java内存动态编译

public class MemoryCompiler {

private static MemoryCompiler compiler = new MemoryCompiler();

private MemoryCompiler(){

}

public static MemoryCompiler getInstance(){

return compiler;

}

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

StringBuilder source = new StringBuilder();

source.append("public class MemoryClass {\n");

source.append("    public boolean m(String v) {\n");

source.append("        return \"e2say\".equals(v);\n");

source.append("    }\n");

source.append("    public int m(int v) {\n");

source.append("        return v*((v+1)-2*3/4);\n");

source.append("    }\n");

source.append("}");

System.out.println(source);

/*1、编译*/

Class> cls = getInstance().compile("MemoryClass", source.toString());

/*2、实例化*/

Object obj = cls.newInstance();

/*3、方法调用*/

Object rtn1 = cls.getMethod("m", String.class).invoke(obj, "e2say");

System.out.println("m(\"e2say\"):"+rtn1);

Object rtn2 = cls.getMethod("m", int.class).invoke(obj, 10);

System.out.println("m(10):"+rtn2);

}

public Class> compile(String className, String content) throws Throwable{

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

DiagnosticCollector diagnostics = new DiagnosticCollector();

ClassFileManager fileManager = new ClassFileManager(compiler.getStandardFileManager(diagnostics, null, null));

URLClassLoader classLoader = (URLClassLoader) JinGuo.class.getClassLoader();

StringBuilder classPath = new StringBuilder();

for(URL url:classLoader.getURLs()){

classPath.append(url.getFile()).append(File.pathSeparator);

}

//System.out.println(classPath);

JavaCompiler.CompilationTask task = compiler.getTask(null,

fileManager,

diagnostics,

Arrays.asList("-encoding", "UTF-8", "-classpath", classPath.toString()),

null,

Arrays.asList(new JavaSourceObject(className, content)));

if(task.call()){

MemoryClassLoader loader = new MemoryClassLoader(classLoader);

JavaClassObject classObject = fileManager.getJavaClassObject(className);

Class> cls = loader.loadClass(className, classObject);

return cls;

}else{

for(Diagnostic extends JavaFileObject> diagnostic:diagnostics.getDiagnostics()){

StringBuffer buf = new StringBuffer();

buf.append("Code:" + diagnostic.getCode() + "\n");

buf.append("Kind:" + diagnostic.getKind() + "\n");

buf.append("Position:" + diagnostic.getPosition() + "\n");

buf.append("Start Position:" + diagnostic.getStartPosition() + "\n");

buf.append("End Position:" + diagnostic.getEndPosition() + "\n");

buf.append("Source:" + diagnostic.getSource() + "\n");

buf.append("Message:" + diagnostic.getMessage(null) + "\n");

buf.append("LineNumber:" + diagnostic.getLineNumber() + "\n");

buf.append("ColumnNumber:" + diagnostic.getColumnNumber() + "\n");

System.out.println(buf.toString());

}

}

return null;

}

/**文件内容为内存中动态拼出的字符串*/

private class JavaSourceObject extends SimpleJavaFileObject {

private CharSequence content;

public JavaSourceObject(String className, CharSequence content) {

super(URI.create("string:///" + className.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);

this.content = content;

}

@Override

public CharSequence getCharContent(boolean ignoreEncodingErrors) {

return content;

}

}

/**编译时class输出至JavaClassObject的ByteArrayOutputStream*/

private class ClassFileManager extends ForwardingJavaFileManager {

public ClassFileManager(StandardJavaFileManager standardManager) {

super(standardManager);

}

private HashMap classMap = new HashMap();

public JavaClassObject getJavaClassObject(String className) {

return classMap.get(className);

}

@Override

public JavaFileObject getJavaFileForOutput(Location location, String className,

JavaFileObject.Kind kind, FileObject sibling) throws IOException {

JavaClassObject classObject = new JavaClassObject(className, kind);

classMap.put(className, classObject);

return classObject;

}

}

private class JavaClassObject extends SimpleJavaFileObject {

protected final ByteArrayOutputStream bos = new ByteArrayOutputStream();

public JavaClassObject(String name, Kind kind) {

super(URI.create("string:///" + name.replace('.', '/') + kind.extension), kind);

}

public byte[] getBytes() {

return bos.toByteArray();

}

@Override

public OutputStream openOutputStream() throws IOException {

return bos;

}

}

/**从内存加载类*/

private class MemoryClassLoader extends URLClassLoader {

public MemoryClassLoader(ClassLoader parent) {

super(new URL[0], parent);

}

public Class> loadClass(String className, JavaClassObject classObject) {

byte[] bytes = classObject.getBytes();

//defineClass方法为protected

return defineClass(className, bytes, 0, bytes.length);

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值