Java 元编程

2022-09-04 21:28:48

我正在用Java做我的第一个真正的项目。我开始适应这门语言,尽管我对动态语言有更多的经验。

我有一个行为类似于以下内容的类:

class Single
{
    public void doActionA() {}
    public void doActionB() {}
    public void doActionC() {}
}

然后我有一个类,它充当这些类的集合(具体来说,它用于2D Sprite库,“操作”是各种转换:旋转,切变,缩放等)。我希望能够执行以下操作:SingleList

class SingleList
{
    public void doActionA() {
        for (Single s : _innerList) {
            s.doActionA();
        }
    }

    ... etc ...
}

有没有办法简单地将方法(或已知的方法列表)推迟到内部列表的每个成员?有什么方法不必专门列出每个方法,然后遍历每个内部成员并手动应用它?

为了使事情变得更加困难,这些方法具有不同的arity,但都是返回类型“void”。


答案 1

不幸的是,Java不容易在运行时创建类,而这正是你所需要的:需要使用必要的存根方法来自动更新以匹配类。SingleListSingle

我可以想到以下方法来解决这个问题:

  1. 使用 Java 反射

    • 优点:
      • 它在 Java 语言中随时可用,您可以轻松找到文档和示例。
    • 缺点:
      • 该类将不再与类接口兼容。SingleListSingle
      • Java 编译器和任何 IDE 通常都无法帮助通过反射调用的方法 - 编译器捕获的错误通常转换为运行时异常。
      • 根据您的使用案例,您可能还会看到明显的性能下降。
  2. 使用构建系统以及某种源代码生成器来自动创建文件。SingleList.java

    • 优点:
      • 设置完成后,您将不必再处理它。
    • 缺点:
      • 设置它有一定程度的难度。
      • 您必须单独确保在任何 JVM 中装入的类(或您的 IDE)实际上与装入的类匹配。SingleListSingle
  3. 手动解决这个问题 - 创建一个接口(例如)或一个供两个类使用的基本抽象类应该会有所帮助,因为任何像样的IDE都会指出未实现的方法。正确的类体系结构将最大限度地减少重复的代码,并且您的 IDE 可能能够帮助生成样板部分。SingleInterface

    • 优点:
      • 没有设置曲线可以克服。
      • 您的 IDE 将始终看到正确的类集。
      • 类体系结构通常会在以后进行改进。
    • 缺点:
      • 一切都是手动的。
  4. 使用字节码生成库(如 JavassistBCEL)动态生成/修改类。SingleList

    • 优点:
      • 这种方法非常强大,从长远来看可以节省大量时间。
    • 缺点:
      • 使用字节码生成库通常不是微不足道的,也不适合胆小的人。
      • 根据编写代码的方式,IDE 及其对动态类的处理也可能存在问题。

答案 2

推荐