Writing and implementing new Java class files duri

2019-02-07 02:15发布

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条回答
萌系小妹纸
2楼-- · 2019-02-07 02:17

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.

查看更多
神经病院院长
3楼-- · 2019-02-07 02:25

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.
查看更多
Ridiculous、
4楼-- · 2019-02-07 02:25

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.

查看更多
可以哭但决不认输i
5楼-- · 2019-02-07 02:44

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.

查看更多
登录 后发表回答