Как выполнить код, записанный в массиве String

337
24 июня 2017, 11:07

Мне нужно чтобы программа выполняла код, записанный в массиве строк. Допустим:

String TEST_STRING = "System.out.println(\"Мама мыла раму\");";
String[] testString = new String[2];
testString[0] = TEST_STRING;
//Здесь каким-то образом выполняется код, записанный в testString[0]
Answer 1

разъясните подробнее постановку задачи, может быть вам и не нужно такое вульгарное решение. От себя советую познакомиться с паттерном "команда". Вот к примеру реализация "пульта управления".

1) У нас есть некоторый набор сущностей с которыми надо взаимодействовать, они могут выполнять действие откатывать его и сообщать свой статус

public class SomeEntity{
private boolean status = false;
public void do() {
    this.status = false;
    //do your code
}
public void undo() {
    this.status = true;
    //undo your code
}
public boolean getStatus() {
    return this.status;
}
}

2)Теперь мы пишем команду для каждого сценария нашего класса

public interface Command {
public void execute();
public void undo();
}

3)За командой прикрепляется сущность с которой она взаимодействует

public class MyCommand implements Command {
private final SomeEntity someEntity;
public MyCommand (SomeEntity someEntity) {
    this.someEntity= someEntity;
}
@Override
public void execute() {
    this.someEntity.do();
}
@Override
public void undo() {
    this.someEntity.undo();
}
}

4)а теперь создадим пульт, который бы знал в лицо объекты с которыми ему взаимодействовать и научим его выполнять макросы

public class Controller {
private final ArrayList<Command> сommands;
public Controller() {
    thisommands = new ArrayList<Command>();
}
public void addCommand(Command сommand) {
    thisommands.addommand);
}
public void executeCommand(int index) {
    if (index < thisommands.size()) {
        thisommands.get(index).execute();
    }else{
        new DoNothingCommand().execute();
        //comand which doing nothing
    }
}
public void undoCommand(int index) {
    if (index < this.undoCommands.size()) {
        this.commands.get(index).undo();
    }else{
        new DoNothingCommand().execute();
    }
}
}

а теперь подумайте сколько всего прикольного можно сделать, вы можете циклом обойти весь список в commands и вызвать их execute() - вот вам и макрос на уровне пульта. Или ещё круче сделать набор макросов на уровне команд: создать Command в котором лежал бы такой-же ArrayList<Command> и execute() который бы их все выполнял. Тогда пульт даже не знает, что внутри одной из его команд лежит целый сценарий, он выполняет всего один execute() и забывает про это.

5) работа с пультом

public static void main(String[] args) {
    Controller myController = new Controller();
    SomeEntry someEnttity = new SomeEntity ();
    //create as much entities as you want...
    myController.addCommand(new SomeCommand(someEntry));
    //Appoint comands for your entities and add them to controller...
    myController.executeCommand(0);
    //press an button
}
Answer 2

Вот еще примитивный пример принта в консоль используя ScriptEngine, но не уверен что это именно то, что вам нужно, думаю в вашем случае скорее Java Compiler API

    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine js = scriptEngineManager.getEngineByName("js");
    try {
         js.eval("print(\"someText\")");
    } catch (ScriptException e) {
        e.printStackTrace();
    }
Answer 3

Ну теоретически это возможно, если код, который нужно выполнить Вы выведете через поток вывода на диске что-то типа YourText.java и следующей же командой его исполните через ShellExecute (Это если вы пишите в Win). Ну так как-то:

      try{

          Process pr = Runtime.getRuntime().exec("cmd /c javac YourText.java");
     //вызов через ShellExecute
     //а всё, что ниже, касается просто вывода результата команды
     BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
         String line = null;
while ((line = input.readLine()) != null)
                System.out.println(line);

int exitVal = pr.waitFor();
System.out.println("Exited with error code " + exitVal);
}
    catch(Exception e1){
e1.printStackTrace();
}

Тут поподробнее: https://habrahabr.ru/post/125210/

READ ALSO
Особенности дебага в Android

Особенности дебага в Android

Происходит отладка Android приложения в IntelliJ IDEA 20171

290
С чего начать изучение Java? [требует правки]

С чего начать изучение Java? [требует правки]

Студент первого курсаИзучаю C#, веб-программирование

297