【问题标题】:Generating Dynamic Class Java生成动态类 Java
【发布时间】:2013-03-08 21:49:42
【问题描述】:

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

【问题讨论】:

  • 但我不需要创建 .java 文件以便编译它
  • 在@Affe 的链接中查看 JavaSourceFromString 示例以获取可能的解决方案。
  • 没有特别要求 javax.tools.JavaFileObject 的实现代表磁盘上的实际文件,不,它可以只是内存中字符串的包装器。 (对不起,并不是要迟钝,只是现在太忙了,无法写出完整的答案,并认为如果我们为您指出正确的方向,您将能够在网络上找到一些对您有所帮助的教程出来。)
  • 但是当我加载类时我需要一个类文件来加载它

标签: java file-io dynamic-compilation dynamic-class


【解决方案1】:

如果你看一下 ClassLoader 类,它有一个方法可以从实际的字节序列中定义一个类。

Java docs for ClassLoader

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

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

【讨论】:

  • 好像有点复杂
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

    这里有一些东西可以帮助您入门 - 我将把将字节码放入对象中的练习留给读者作为练习。 (如果你在这方面使用一点SimpleFileVisitor 工作并不难。Check out 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。

    【讨论】:

    • 这就是我做的问题是我不想创建任何物理文件
    • ...但是您确实提到您正在某个地方编译该类,对吗?如果您有大量 .class 文件,这不是一个大问题;完成后可以安全地删除它们...
    • 我知道它看起来不干净
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 2019-03-03
    • 2019-12-18
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    相关资源
    最近更新 更多