【问题标题】:Execute code from a String in Java从 Java 中的字符串执行代码
【发布时间】:2017-08-22 14:55:07
【问题描述】:

我进行了一些搜索,似乎有一些人提出了类似的问题,但没有一个是我想要的(有些人建议了一些脚本的东西,但我没有足够的了解我是什么这样做我只想在可能的情况下使用 java)。

我需要能够从字符串中读取代码行,然后在 Java 中执行它们(像这样):

String code = "System.out.println(\"Test code\");";

很多阅读这篇文章的人可能会问你为什么不直接执行

System.out.println("Test code");

但我想从 Strings 中执行 println 方法以外的代码。

是否可以单独使用java执行代码,如果可以,它会如何编译??

【问题讨论】:

  • 将字符串写入file.java,编译运行...
  • 你为什么要这样做?
  • @JohnD 不,代码总是必须编译的。
  • This answer 可能会提供一些指示。
  • @JohnD 据我了解,您不需要编译任何东西。您只想输入一个字符串并在记事本中“键入”1to1。对吗?

标签: java string execution


【解决方案1】:

您不能像我想象的那样轻松地做到这一点。你所描述的那种东西是你可能在动态语言中看到的东西。 Java 在很大程度上不是一种动态语言 - 这是它的特点的一部分。

如果你的类路径中有tools.jar,你可以在你的Java程序中编译Java代码:

com.sun.tools.javac.Main javac = new com.sun.tools.javac.Main();
String[] options = new String[] {
    "-classpath", classpath, "-d", outputDir, filename
};
javac.compile(options);

从那里你可以与类加载器搏斗,加载你编译的类,然后运行它。

然而,这不是使用 Java 的简单或主流方式,而且通常人们不会这样做,因为这既不是好的做法,也不是必需的。用户提供的代码在编译后无法运行是一种安全特性。


如果您想要一种更加动态的语言,在 Java 生态系统中,您可以查看 Groovy。


或者,您可以运行用户提供的 Javascript,使用 Java Scripting API 使其对您的 Java 程序数据进行受控访问。

【讨论】:

  • 像 com.sun ... 这样的内部类是不好的提议,特别是当官方 javax.tools.JavaCompiler 存在时
  • 我的类路径中没有 tools.jar,我使用 IntelliJ 如何添加它?
  • 完整的JDK(JRE没有这个jar)
  • @JohnD 不要。我希望在答案的正文中劝阻你。这很困难,你需要有经验才能做到。一旦你有经验,你就会明白为什么它不明智。
【解决方案2】:

可以,但是java代码不能这样执行,它没有被解释,需要先编译。 所以你需要把你的字符串放到另一个java文件的main函数中,然后编译,最后运行。

你可能需要这个:http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

【讨论】:

    【解决方案3】:

    如果我理解正确,您想在 java 控制台中输入一个字符串。然后应该在外部程序中神奇地输入这个给定的字符串。如果我没有理解正确,我将再次删除该答案。

    public class Test {
    
        public static void main(String[] args) throws IOException, ClassNotFoundException, Exception {
        Robot robot = new Robot();
        String text = "Hello";
        File file = File.createTempFile("tmp", ".txt");
    
        if (Desktop.isDesktopSupported()) {
            Desktop.getDesktop().edit(file);
            Thread.sleep(1000);
        } else {
            // dunno, up to you to handle this
        }
        for (char c : text.toCharArray()) {
            int keyEvent = KeyEvent.getExtendedKeyCodeForChar(c);
            robot.keyPress(keyEvent);
            Thread.sleep(500);
        }
        }
    }
    

    如果您运行此基本代码,记事本应该会打开,并且正在输入文本 Hello。这就是我为你准备的。现在您需要做的是使用Scanner 从控制台获取字符串,而不是从静态字符串中获取。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-27
      • 2015-11-08
      • 1970-01-01
      • 2021-11-13
      • 2017-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多