运行String中包含的一段代码

时间:2010-12-08 15:33:50

标签: java reflection

我在String中有一段Java代码。

String javaCode = "if(polishScreenHeight >= 200 && " +
    "polishScreenHeight <= 235 && polishScreenWidth >= 220) { }";

是否可以将此Java String转换为Java语句并运行它?可能使用Java反射?

9 个答案:

答案 0 :(得分:22)

正如已经建议的那样,您可以使用Compiler API动态编译,保存和运行代码。

另一个简洁的选择是使用beanshell。 Beanshell不再积极开发,但我可以保证它的可靠性,我已经在多个生产项目中成功使用它。

答案 1 :(得分:9)

使用BeanShell。 how to use it from Java上有一个页面。

答案 2 :(得分:2)

Beanshell(正如Boris所建议的)是一种“执行”java源代码的方法。但看起来,你想“执行”可以与编译类交互的片段。您的示例包含变量名称。

反射肯定没有用,因为反射的目标是类(“classfiles”)。

可以尝试定义一个完整的类(“有效的java源文件”),编译并加载它(url classloader)。然后你应该能够使用“实时生成的类”中的方法。但是一旦一个类被加载,你就无法摆脱它(卸载),所以这只能工作一次(AFAIK)。

答案 3 :(得分:1)

据我所知,没有简单的方法可以做到这一点。

但是,在Java 6以后,可以使用javax.tools.Compiler编译完整类的源代码。然后可以加载和执行已编译的类。但我不认为这会达到你想要的效果。

答案 4 :(得分:1)

另一种方法是将代码作为Groovy代码执行,有关示例,请参阅this

答案 5 :(得分:1)

您可以使用此代码来运行使用此代码的方法 new Statement(Object target, String methodName, Object[] arguments).execute();

import java.beans.Statement;

public class HelloWorld {

  public void method_name(String name) {
      System.out.println(name);
  }

  public static void main(String[] args) throws Exception {
      HelloWorld h = new HelloWorld();
      new Statement(h, "method_name", new Object[]{"Hello world"}).execute();
  }
 }

答案 6 :(得分:1)

  1. 请重新评估您的设计,这应该是您的最后选择。
  2. 您应验证将执行的String的完整性,以避免将来发生注入攻击。

现在,如果您可以将String作为 JavaScript 使用,则下面的代码应该有所帮助,

public class EvalScript {

        public static void main(String[] args) throws Exception {
            // create a script engine manager
            ScriptEngineManager factory = new ScriptEngineManager();
            // create a JavaScript engine
            ScriptEngine engine = factory.getEngineByName("JavaScript");

            // below JS function is executed.
            /*
             * student object value will be provided by the program as the JSON String.
            function checkStudentElgibility(student){
              if(student.age >= 10 && student.currentGrade >= 5){
                return true;
              }
            }
            // student object value will be provided by the program as the JSON String

            checkStudentElgibility(student);
            */

            String studentJsonString = "{\n" + 
                    "  \"age\" : 10,\n" + 
                    "  \"currentGrade\" : 5\n" + 
                    "}";
            String javaScriptFunctionString = "function checkStudentElgibility(student){\n" + 
                    "  if(student.age >= 10 && student.currentGrade >= 5){\n" + 
                    "    return true;\n" + 
                    "  }\n" + 
                    "}\n" + 
                    "checkStudentElgibility(student);";

            StringBuilder javaScriptString = new StringBuilder();
            javaScriptString.append("student=");
                javaScriptString.append(studentJsonString);
            javaScriptString.append("\n");
            javaScriptString.append(javaScriptFunctionString);

           Object object = engine.eval(javaScriptString.toString());

           System.out.println(object);

           // You can also pass the object as follows,

           // evaluate JavaScript code that defines an object with one method
            engine.eval("var obj = new Object()");
            engine.eval("obj.hello = function(name) { print('Hello, ' + name) 
              }");

           // expose object defined in the script to the Java application
             Object obj = engine.get("obj");

         // create an Invocable object by casting the script engine object
            Invocable inv = (Invocable) engine;

      // invoke the method named "hello" on the object defined in the
     // in js Object with "Script Method" as parameter 

               inv.invokeMethod(obj, "hello", "Script Method!");





    // You can also use Java Objects as Java script object and you can also pass Objects as reference inside Java script function


                            String jsString = "    var obj = new Object()\n" + 
                        "    var ArrayList = Java.type(\"java.util.ArrayList\");\n" +
                        "    var customSizeArrayList = new ArrayList(16);\n" + 
                        "    obj.hello = function(name) { \n" + 
                        "       customSizeArrayList(name);  \n" + 
                        "       print('Hello, ' + name) \n" + 
                        "    }";
            }


}

参考: https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/prog_guide/javascript.html#A1147187

答案 7 :(得分:0)

试用JavaCompiler API。

其他人比我更好地回答了这个问题: Convert String to Code

在实际使用这样的东西之前要小心......

答案 8 :(得分:0)

它不是Java,但由于pgras已经建议您可以像这样使用GrooyScript:

    Binding binding = new Binding();
    GroovyShell shell = new GroovyShell(binding);

    String[] strings = new String[]{"World", "Groovy"};
    shell.setVariable("args", strings);

    String script = "return \"Hello \" + args[1]";
    String value = (String) shell.evaluate(script);
    System.out.println(value); // Hello Groovy