【问题标题】:Dynamic class creation - Java动态类创建 - Java
【发布时间】:2016-10-24 01:32:25
【问题描述】:

有没有办法动态地创建一个包含类代码的字符串的类,或者以相同的方式将方法添加到先前创建的现有类?

用例场景:学生正在参加考试,他必须在没有 IDE 的情况下编写一些方法(因此他提交了一个简单的字符串)。我想要实现的是一种对他的提交执行简单单元测试的方法。例如,教授提供的运行单元测试的可点击按钮。

抱歉我的英语不好,提前致谢!

【问题讨论】:

  • 所以学生交了一个.txt文件?为什么不是 .java 文件——它可以很容易地添加到项目中,所以没有这种奇怪的问题。
  • 学生面前有一个文本框,有两个按钮“提交”和“运行测试”。在这个文本框中,他有类代码,他必须编辑它添加 2 或 3 个方法。当他单击“运行测试”按钮时,我想像将所有类代码放入一个字符串,使用给定名称从该字符串动态创建类的神奇方法,从代码运行junit测试,把结果还给他。
  • @TobiasBrösamle '项目'?你指的是哪个项目? OP 需要在没有 IDE 的情况下对以文本形式提交的源代码进行某种自动化单元测试。
  • 查看Javassist,了解如何在运行时创建新类或修改现有类。在this 示例中可以看到如何将代码添加到现有类文件中,尽管这样做的原因略有不同。
  • @Adriaan Koster 完全是,我没有项目。

标签: java dynamic reflection classloader reloading


【解决方案1】:

KIT(德国卡尔斯鲁厄的一所大学)创建了一个工具来测试学生的编程任务。可以看看here

【讨论】:

    【解决方案2】:

    学生将提交 Java 源代码,而不是字节码。 Java 源代码必须先使用 Java 编译器编译成字节码,然后才能被类加载器加载。您可以通过以编程方式调用编译器来做到这一点(请参阅this 答案)。在运行时加载这个新的.class 文件的字节码可以这样完成:

    class NetworkClassLoader extends ClassLoader {
         String host;
         int port;
    
         public Class findClass(String name) {
             byte[] b = loadClassData(name);
             return defineClass(name, b, 0, b.length);
         }
    
         private byte[] loadClassData(String name) {
             // load the class data from the connection
              . . .
         }
     }
    

    (来自here 的示例,感谢@Robert)。

    一旦你有了一个实例,你就可以将它提供给你的测试应用来运行一些测试并获得结果。

    让提交的类实现您定义的接口并让您的测试代码针对该接口进行测试是最简单的。这样,您的测试将预先编译,并且仍然可以在运行时处理动态编译和实例化的提交。

    【讨论】:

    • 在运行时通过标准类加载器和loadClass 加载动态创建的类,恕我直言,这不是一个好的解决方案。更好的是直接从字节码数据创建类的自定义 ClassLoader。见"NetworkClassLoader" example in JavaDoc
    • 我猜你是对的,因为新类不会在类路径上。没有考虑足够长的时间;-D
    猜你喜欢
    • 2011-04-05
    • 1970-01-01
    • 2011-04-16
    • 2021-05-02
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    • 2012-09-29
    相关资源
    最近更新 更多