zoukankan      html  css  js  c++  java
  • Java版的实现JavaScript中的eval()函数

    实现步骤:

    1.自定义一个Java类,该Java类中定义一个方法来包含需要被运行的代码。
    2.动态编译刚刚生成的Java源码,不在磁盘上生成源码,而是直接编译内存中的Java源码。
    3.动态加载刚刚创建编译的Java二进制码,编译好的Java二进制码不是在磁盘上,而是放在内存中,并定义自己的类加载器,负责加载内存中的class文件。
    4.通过反射运行前一步加载的类。

    import java.util.Arrays;
    import javax.tools.SimpleJavaFileObject;
    import javax.tools.JavaFileObject;
    import javax.tools.JavaCompiler;
    import javax.tools.ToolProvider;
    import javax.tools.DiagnosticCollector;
    import java.net.URI;


    /**
    * Description:
    * <br/>网站: <a href="http://www.crazyit.org" mce_href="http://www.crazyit.org">疯狂Java联盟</a>
    * <br/>Copyright (C), 2001-2010, Leeyohn
    * <br/>This program is protected by copyright laws.
    * <br/>Program Name:
    * <br/>Date:
    * @author Leeyohn leeyohn@hotmail.com
    * @version 1.0
    */

    public class MyClassLoader
    extends ClassLoader
    {
    @Override
    public Class<?> findClass(String str) throws ClassNotFoundException
    {
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    //用于诊断源代码编译错误的对象
    DiagnosticCollector diagnostics = new DiagnosticCollector();
    //内存中的源代码保存在一个从JavaFileObject继承的类中
    JavaFileObject file = new JavaSourceFromString("Temp", str.toString());
    Iterable compilationUnits = Arrays.asList(file);
    //建立一个编译任务
    JavaCompiler.CompilationTask task = compiler.getTask(null, null, null, null, null, compilationUnits);
    //编译源程序
    boolean result = task.call();
    if (result)
    {
    return Class.forName("Temp");
    }
    return null;
    }
    }

    class JavaSourceFromString extends SimpleJavaFileObject
    {
    private String name;
    private String code;
    public JavaSourceFromString(String name, String code)
    {
    super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
    this.code = code;
    }

    public CharSequence getCharContent(boolean ignoreEncodingErrors)
    {
    return code;
    }
    }

    import java.lang.reflect.Method;

    /**
    * Description:
    * <br/>网站: <a href="http://www.crazyit.org" mce_href="http://www.crazyit.org">疯狂Java联盟</a>
    * <br/>Copyright (C), 2001-2010, Leeyohn
    * <br/>This program is protected by copyright laws.
    * <br/>Program Name:
    * <br/>Date:
    * @author Leeyohn leeyohn@hotmail.com
    * @version 1.0
    */

    public class Eval
    {
    public static Object eval(String str) throws Exception
    {
    StringBuffer sb = new StringBuffer();
    sb.append("public class Temp");
    sb.append("{");
    sb.append(" public Object getObject()");
    sb.append(" {");
    sb.append(" " + str + "return new Object();");
    sb.append(" }");
    sb.append("}");
    //调用自定义类加载器加载编译在内存中class文件
    Class clazz = new MyClassLoader().findClass(sb.toString());
    Method method = clazz.getMethod("getObject");
    //通过反射调用方法
    return method.invoke(clazz.newInstance());
    }

    public static void main(String[] args) throws Exception
    {
    Object rval = eval("System.out.println(/"Hello World/");");
    System.out.println(rval);
    }
    }

  • 相关阅读:
    IfcFurnishingElementType
    IfcRelAssociatesClassification
    IfcRelAssociatesDocument
    IfcContext
    IfcRelAssociatesMaterial
    我是高敏感的人,你呢?
    介绍一本红色的书
    矫枉必须过正
    大家都在说的民法典,与我有何关系?
    线上Kafka突发rebalance异常,如何快速解决?
  • 原文地址:https://www.cnblogs.com/richelle009/p/4495410.html
Copyright © 2011-2022 走看看