Есть Java-файл. Допустим с именем Example.java
и в нем, есть код:
public class EXAMPLE {
public static void main(String[] args) {
int x = 10;
System.out.println(x);
}
}
Как мне изменить значение x = 10
на x = 30
через другую Java-программу?
Как должна, в теории, произойти изменение(как я это вижу):
Другая java-программа (допустим, Example2.java
) открывает файл EXAMPLE.java
, считывает все строки и находит ту самую - x = 10
. Далее эта строка удаляется и на месте нее появляется x = 10
. Из-за того, что информация должна куда-то записываться во время такх изменений - она будет записываться в файл EXAMPLE_temp.java
. После завершения процесса изменения переменной, EXAMPLE_temp.java
переименовывается в EXAMPLE.java
и генерируется новый EXAMPLE.class
. Дальше, при компиляции новой версии файла EXAMPLE.java
, в консоли должно протсто вывестись:
30
Почему это важно?
В нынешний момент, чтобы изменить ОДНО ЧИСЛО в файле, мне приходится держать отдельно *.txt документ, в который я произвожу изменение данных.
Почему я не пробовал сам "поэкспериментировать/почитать"? .
Потому что мне интересно узнать, что могут посоветовать знающие и прошаренные люди. Мне интересен разный подход к решению данной проблемы
(Простите за офф-топик, но без этого никак.)
Работа с исходным кодом как с текстом - путь недостойный самурая. Знающие и прошаренные люди советуют использовать API компилятора для разбора исходника в абстрактное синтаксическое дерево (AST), модификацию этого дерева и его компиляцию всё тем же API компилятора.
Example.java
public class Example {
public static void main(String[] args) {
int x = 10;
System.out.println(x);
}
}
JavaSourceFromString.java
import java.net.URI;
import javax.tools.SimpleJavaFileObject;
/**
* Класс эмулирующий для компилятора файлы исходного кода
* и позволяющий компилировать код прямо из памяти
*/
class JavaSourceFromString extends SimpleJavaFileObject {
private final String code;
public JavaSourceFromString(String name, String code) {
super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
Translator.java
import com.sun.source.util.JavacTask;
import com.sun.tools.javac.api.BasicJavacTask;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeTranslator;
import com.sun.tools.javac.util.Context;
// Класс обхода и модификации AST
public class Translator extends TreeTranslator {
private final TreeMaker treeMaker;
private final JavacElements elements;
public Translator(JavacTask task) {
Context context = ((BasicJavacTask) task).getContext();
treeMaker = TreeMaker.instance(context);
elements = JavacElements.instance(context);
}
// Встречено определение переменной
@Override
public void visitVarDef(JCTree.JCVariableDecl tree) {
String varName = tree.getName().toString();
if ("x".equals(varName)) { // Переменная имеет имя "x"
// Подменяем определение, заменяя литерал
result = treeMaker.VarDef(tree.getModifiers(), tree.getName(), tree.vartype, treeMaker.Literal(30));
}
else {
super.visitVarDef(tree);
}
}
}
Parser.java
import java.util.List;
import java.util.ArrayList;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.util.JavacTask;
import com.sun.tools.javac.tree.JCTree;
public class Parser {
public static void main(String[] args) throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
// Считываем исходный файл
Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjects("Example.java");
JavacTask javac = (JavacTask) compiler.getTask(null, fileManager, null, null, null, fileObjects);
Translator translator = new Translator(javac);
List<JavaFileObject> sources = new ArrayList<>();
// Парсим исходный файл в деревья
for (CompilationUnitTree tree : javac.parse()) {
// Модифицируем деревья
((JCTree.JCCompilationUnit) tree).accept(translator);
// Сохраняем результат в память
sources.add(new JavaSourceFromString("Example", tree.toString()));
}
// Компилируем
CompilationTask task = compiler.getTask(null, null, null, null, null, sources);
task.call();
}
}
Виртуальный выделенный сервер (VDS) становится отличным выбором
Есть с трока с col-lg-12У нее d-flex
У меня есть store со значениями, где хранятся типы данных и их обозначения с id и тд