在运行时编写和实现新的 Java 类文件

发布于 2024-10-27 15:47:34 字数 1478 浏览 7 评论 0 原文

是否有可能以某种方式将新的 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

Bonjour°[大白 2024-11-03 15:47:34

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.

秋意浓 2024-11-03 15:47:34

您应该研究使用 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.

财迷小姐 2024-11-03 15:47:34

你实际上想要一个编译器 - 看看 java.lang.Compiler:

http://download.oracle.com/javase/6/docs/api/java/lang/Compiler.html

您可以通过编译新的 .class 文件来加载不同的类。

这不允许您更改加载的类。为此,您还需要一个 java.lang.instrument.ClassFileTransformer 并且必须在运行时在命令行上指定。

回答您的其他一些问题:

  • 如果文件是从 .java 编译的,它将经历与在其他地方编译的文件相同的检查。
  • 如果您使用合适的工具(例如 BCEL 或 ASM)创建字节代码,那么它仍然会经过多次检查以证明其内部一致。
  • 如果您更改跑步类别,您可以更改的内容将受到限制。

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:

  • If a file is compiled from .java it will go through the same checks as one compiled elsewhere.
  • If you create the byte code using suitable tools (BCEL or ASM for example) then it still goes through multiple checks to prove it is internally consistent.
  • If you change a running classes, you are limited in what you can change.
遇见了你 2024-11-03 15:47:34

再抛出一个: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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文