5

我通过将所有代码写入 java 文件,将 java 文件编译为类文件,然后使用 URLClassLoader 加载类文件,在我的 java 程序中生成一个动态类。这样做的问题是它在我的计算机上创建了很多文件。他们是一种只创建“虚拟文件”(文件对象)而不生成任何实际文件的方法吗,因为我这样做的方式需要时间并且看起来不干净且效率低下。

4

3 回答 3

1

字节码生成和操作库允许您在内存中动态修改和生成类。Javassist可能是最容易开始的,因为它允许使用 Java 语法。

它们也往往比整个独立编译器更轻。

于 2013-03-20T00:30:51.907 回答
1

如果您查看 ClassLoader 类,它有一个从实际字节序列定义类的方法。

类加载器的 Java 文档

我承认我没有使用过这么低级别的类加载器,但我的理解是这是一个模板模式,其中基础 ClassLoader 类知道如何根据原始字节码在 VM 中创建一个类。子类负责确定在哪里可以找到给定类的字节码。

因此,您的解决方案可能是完全停止使用 URLClassLoader 并自己扩展 ClassLoader。

于 2013-03-20T00:00:51.467 回答
0

一个(更)直接的解决方案是执行以下操作:

  • 将你的类文件编译到一个公共目录中
  • 创建一个ClassLoader扩展的自定义ClassLoader
  • 使用它ClassLoader来读取 .class 文件。

这里有一些可以帮助您入门的内容 - 我将把将字节码放入对象的练习留给读者作为练习。SimpleFileVisitor(如果你在这方面做一些工作,这 并不是很困难。查看 Java.NIO。

public class CustomClassLoader extends ClassLoader {

    @Override
    public Class findClass(String binaryClassName) {
        byte[] b = customLoadClassData(binaryClassName);
        return defineClass(binaryClassName, b, 0, b.length);
    }

    private byte[] customLoadClassData(String binaryClassName) {
        // Be sure to read in the specific .class file you want.
        // A tip is to handle this *outside* of this class.
    }

}

然后你可以像这样使用它:

CustomClassLoader loader = new CustomClassLoader();
Class clazz = loader.findClass("com.stackoverflow.some.binary.name");

...前提是它没有抛出异常或返回 null。

于 2013-03-20T00:13:55.483 回答