是否有可能以某种方式将新的 Java 类“导入”到正在运行的程序中并使用它?
我可以让程序创建一个“.java”类型的新文件,然后将其包含在项目文件中并引用它,而无需重新启动程序吗?
以下是我的意思的一个示例:
import java.io.*;
public class Program {
File JClass = new File("JClass.java");
public static BufferedWriter out = null;
public static void main(String[] args) {
try {
out = new BufferedWriter(new FileWriter("JClass.java"));
out.write("public abstract class JClass {");
out.newLine();
out.newLine();
out.write(" public void printSomething(String a) {");
out.newLine();
out.write(" System.out.println(a);");
out.newLine();
out.write(" }");
out.newLine();
out.write("}");
out.close();
} catch (IOException e)
{
System.exit(-1);
}
//Somehow import JClass.java as a class here
JClass.printSomething("Yay! It worked!");
}
}
生成的“JClass.java”文件:
public abstract class JClass {
public void printSomething(String a) {
System.out.println(a);
}
}
同样,是否可以创建项目源文件之一的副本,编辑文件中的代码,然后以某种方式强制进行更改正在运行的程序?
目前我不太关心实际应用。我只是在探索与编程相关的不同想法。我也明白这有可能引发各种灾难。编辑正在运行的代码,并动态包含类(我不认为在构建项目时会像其他类那样检查错误)可能会产生非常不可预测的结果。我只是想尝试一下这个想法。
也就是说,如果有人有任何有用的警告或需要注意的事情,我将不胜感激。否则,如果人们不要回答“这是一个坏主意”或“有更简单更好的方法来解决问题”,我将不胜感激。我并不是想解决这个问题。我只是在探索这个想法。
那么,这可能吗?
Is it possible to somehow 'import' a new Java class into a running program and make use of it?
Could I have a program create a new File of type '.java' and then include it in the project files and reference it without having to restart the program?
The following is an example of what I mean:
import java.io.*;
public class Program {
File JClass = new File("JClass.java");
public static BufferedWriter out = null;
public static void main(String[] args) {
try {
out = new BufferedWriter(new FileWriter("JClass.java"));
out.write("public abstract class JClass {");
out.newLine();
out.newLine();
out.write(" public void printSomething(String a) {");
out.newLine();
out.write(" System.out.println(a);");
out.newLine();
out.write(" }");
out.newLine();
out.write("}");
out.close();
} catch (IOException e)
{
System.exit(-1);
}
//Somehow import JClass.java as a class here
JClass.printSomething("Yay! It worked!");
}
}
Resulting 'JClass.java' file:
public abstract class JClass {
public void printSomething(String a) {
System.out.println(a);
}
}
Similarly, would it be possible to create a copy of one of the project's source files, edit the code in the file, and then somehow force the changes upon the running program?
I do not care so much about practical application at this point. I am merely exploring different ideas I have had relating to programming. I also understand that this is potential for all sorts of disaster. Editing running code, and including classes on the fly (which I don't imagine would be checked for errors as the other classes are when the project is built), could have very unpredictable results. I merely want to play around with the idea.
That said, if anyone has any HELPFUL warnings or things to look out for, I would appreciate them. Otherwise, I would appreciate if people kept from responding 'This is a bad idea' or 'there are easier and better ways to solve problems'. I am NOT trying to solve a problem with this. I am only exploring the idea.
So, is this possible?
发布评论
评论(4)
Javassist 允许您在运行时修改现有类并创建新类。
http://www.csg.is.titech.ac.jp/~ chiba/javassist/
在 Javassist 教程中 有一个部分用于从头开始定义一个新类。查看 API 以了解如何添加新方法等等。查看 CtNewMethod.make。
Javassist 是 JBoss 用来实现面向方面编程的工具。
您还可以查看 EATS(仪器方法将很有趣),它利用 Javassist 在运行时向现有方法添加新代码。 Eats 还没有发布版本,但它可以工作:o
JPDA 提供了一些修改 JVM 已加载并运行的类的机制。
Javassist will let you modify existing classes and create new classes at run time.
http://www.csg.is.titech.ac.jp/~chiba/javassist/
In the Javassist tutorial there is a section for defining a new class from scratch. Check out the API to see how to add new methods and so on. Check out CtNewMethod.make in the Javassist API.
Javassist is what is used by JBoss to implement aspect oriented programming.
You can also check out EATS (the instrument method will be of interest) which makes use of Javassist to add new code to existing methods at runtime. Eats isn't at a release version, but it works :o
JPDA provides some mechanisms for modifying classes that are already loaded by and running in the JVM.
您应该研究使用 ClassLoader
进行动态类加载http://download.oracle.com/javase/1.5.0/docs/api/java/lang/ClassLoader.html
还有一些机制可以用来编译类,但这可能不会是 AS对你有用。
You should look into on the fly class loading with ClassLoader
http://download.oracle.com/javase/1.5.0/docs/api/java/lang/ClassLoader.html
There are also mechanisms you can use to compile classes, but that's probably not going to be AS useful to you.
你实际上想要一个编译器 - 看看 java.lang.Compiler:
http://download.oracle.com/javase/6/docs/api/java/lang/Compiler.html
您可以通过编译新的 .class 文件来加载不同的类。
这不允许您更改加载的类。为此,您还需要一个 java.lang.instrument.ClassFileTransformer 并且必须在运行时在命令行上指定。
回答您的其他一些问题:
You actually want a Compiler - look at java.lang.Compiler:
http://download.oracle.com/javase/6/docs/api/java/lang/Compiler.html
You can load a different class this way by compiling a new .class file.
This does not let you change a loaded class. To do that you also need a java.lang.instrument.ClassFileTransformer and that has to be specified on the command-line at runtime.
To answer some of your other questions:
再抛出一个:Eclipse Java 编译器。与 BCEL、ASM 或 Jasmin 不同,您不需要了解汇编。 ECJ只是一个用Java编写的Java编译器。
Throwing one more out there: the Eclipse Java Compiler. Unlike BCEL, ASM, or Jasmin, you don't need to know assembly. ECJ is just a Java compiler written in Java.