2013-07-12 35 views
11

Vì lý do gỡ lỗi, tôi muốn có thể chạy mã được nhập thông qua bảng điều khiển. Ví dụ:Chạy mã từ một chuỗi trong Java

BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
while(true){ 
    String str = br.readLine(); //This can return 'a = 5;','b = "Text";' or 'pckg.example.MyClass.run(5);' 
    if(str == null) 
     return; 
    runCode(str); //How would I do this? 
} 
+7

câu hỏi thực sự là: ** ** tại sao bạn muốn làm điều này ... – Dariusz

+1

Chúng ta hãy giả định cho một phân chia thứ hai này có thể ... nhưng chỉ nghĩ Java sẽ biên dịch mã thời gian chạy của bạn như thế nào? – AurA

+2

Những gì bạn cần có thể là [trình thông dịch Java] (http://stackoverflow.com/questions/3504396/java-interpreter). – LaurentG

Trả lời

3

Nếu mã là trong JavaScript sau đó bạn có thể chạy nó với động cơ JavaScript:

Object res = new ScriptEngineManager().getEngineByName("js").eval(str); 

engine JavaScript là một phần của Java SE kể từ 1.6. Xem hướng dẫn này http://download.java.net/jdk8/docs/technotes/guides/scripting/programmer_guide/index.html để biết chi tiết

+0

Ngoài ra còn có các ngôn ngữ kịch bản khác, như BeanShell, tập hợp con java. –

+0

Nếu kịch bản là tùy chọn thì tại sao lại đi xa java? Có Scala, Groovy cũng JRuby và tất cả mọi người dường như yêu JRuby hiệu suất khôn ngoan. – Bnrdo

+0

nếu bạn đang sử dụng java8, tôi sẽ sử dụng nudge4j https://lorenzoongithub.github.io/nudge4j/ – Zo72

0

Vì điều này, bạn có thể muốn xem xét Java Compiler API. Tôi đã không nghiên cứu nhiều như thế nào công trình này, nhưng nó cho phép bạn tải một tập tin java, biên dịch và tải các lớp học trong một hệ thống đã chạy. Có lẽ nó có thể được bổ sung vào việc chấp nhận đầu vào từ giao diện điều khiển.

+0

Phương pháp này có nghĩa là tạo một tệp, viết lớp và mã để nó, biên dịch nó, mở nó, chạy mã ... Không có vẻ là cách tốt nhất để chạy một dòng mã ... – user2555349

3

Bạn có thể sử dụng API tập lệnh Java nằm trong Gói javax.script. Ở đó bạn có thể bao gồm một số ngôn ngữ kịch bản như bsh chẳng hạn.

Bạn có thể tìm thấy programmer's guide trên trang web của Oracle.

Tê giác, một số loại JavaScript đã được bao gồm trong JVM của Oracle.

0

Đối với trình biên dịch chung, bạn có thể sử dụng Janino để cho phép bạn biên dịch và chạy mã Java. expression evaluator có thể giúp bạn làm ví dụ.

Nếu bạn chỉ đang tìm cách đánh giá biểu thức trong khi gỡ lỗi thì Eclispe có Display view cho phép bạn thực hiện các biểu thức. Xem this question.

4

VUI LÒNG KHÔNG thực sự sử dụng NÀY

Tôi đã theo giả định bạn muốn đánh giá một chuỗi như mã Java, không phải một số động cơ kịch bản như Javascript, vì vậy tôi tạo này trên một ý thích sau khi đọc this, sử dụng nhãn API trình biên dịch được đề cập. Nó có thể là thực hành rất xấu nhưng nó (phần nào) hoạt động như bạn muốn. Tôi nghi ngờ nó sẽ được sử dụng nhiều trong gỡ lỗi vì nó chạy mã trong bối cảnh của một lớp mới. Sử dụng mẫu được bao gồm ở dưới cùng.

import javax.tools.JavaCompiler; 
import javax.tools.StandardJavaFileManager; 
import javax.tools.ToolProvider; 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.URL; 
import java.net.URLClassLoader; 
import java.util.Arrays; 

public class main { 
    public static void runCode(String s) throws Exception{ 
     JavaCompiler jc = ToolProvider.getSystemJavaCompiler(); 
     StandardJavaFileManager sjfm = jc.getStandardFileManager(null, null, null); 
     File jf = new File("test.java"); //create file in current working directory 
     PrintWriter pw = new PrintWriter(jf); 
     pw.println("public class test {public static void main(){"+s+"}}"); 
     pw.close(); 
     Iterable fO = sjfm.getJavaFileObjects(jf); 
     if(!jc.getTask(null,sjfm,null,null,null,fO).call()) { //compile the code 
      throw new Exception("compilation failed"); 
     } 
     URL[] urls = new URL[]{new File("").toURI().toURL()}; //use current working directory 
     URLClassLoader ucl = new URLClassLoader(urls); 
     Object o= ucl.loadClass("test").newInstance(); 
     o.getClass().getMethod("main").invoke(o); 

    } 
    public static void main(String[] args) { 
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
     while(true){ 
      try { 
      String str = br.readLine(); //This can return 'a = 5;','b = "Text";' or 'pckg.example.MyClass.run(5);' 
      if(str == null) 
       return; 

      runCode(str); //How would I do this? 
      } catch(Exception e) { 
       e.printStackTrace(); 
      } 
     } 

    } 
} 
//command line 
> System.out.println("hello"); 
hello 
> System.out.println(3+2+3+4+5+2); 
19 
> for(int i = 0; i < 10; i++) {System.out.println(i);} 
0 
1 
2 
3 
4 
5 
6 
7 
8 
9 

Với SimpleJavaFileObject bạn thực sự có thể tránh sử dụng một tập tin, như thể hiện here, nhưng cú pháp có vẻ hơi rườm rà vì vậy tôi chỉ lựa chọn một tập tin trong thư mục làm việc hiện hành.

EDIT: Convert String to Code cung cấp một cách tiếp cận tương tự nhưng nó không đầy đủ fleshed ra

Các vấn đề liên quan