【问题标题】:Groovy static generic typeGroovy 静态泛型类型
【发布时间】:2010-10-09 18:07:05
【问题描述】:

我一直在尝试摆脱 DAO,转而使用 Java 中的 ActiveRecord 类实体,但泛型不允许我拥有我想要的全部功能(如静态查找器)。 Groovy 以某种方式做到了,但我很困惑为什么。鉴于以下情况:

class ActiveRecord<T> {
   static Class<T> genericType;
   ActiveRecord() {
     genericType = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
   }
   static T find(Serializable id) { return EntityManagerHolder.find(genericType, id); }
   void save() { EntityManagerHolder.persist(this); }
}

@Entity @Table(name="TEST")
class FakeTable extends ActiveRecord<FakeTable> {
   @Id @GeneratedValue(strategy = GenerationType.AUTO)
   Long id;
   String status;
   String type;
   static void main(args) {
      FakeTable t = new FakeTable();
      t.status = "TESTING";
      t.save();
      println FakeTable.find(t.id);
   }
}

此代码有效(使用排除的 JPA 内容),但我不确定为什么我能够声明

static Class<T> genericType;

编译器在编译实际的 Java 类之前会做一些魔术吗?也许 groovy 编译器将 T 替换为生成的 Java 类中的实际类名?

在严格的 Java 中,我可以从 find 方法返回类型和类声明中访问泛型类型,但两者都被擦除为 Object。这是有道理的,Groovy 也是如此,但在 Java 中,上面的代码行错误并显示类似于“无法引用非静态 T”的消息。

【问题讨论】:

    标签: java generics activerecord groovy


    【解决方案1】:

    Groovy 不是静态类型的。我想你会发现它会在编译时擦除 T ,甚至不用费心去弄清楚它不在范围内;它与 Groovy 无关。

    【讨论】:

    • 很高兴知道!我没有做太多常规开发。看来我需要多读一点。
    【解决方案2】:

    您将遇到的主要问题是在 Java 和 Groovy 中,静态方法不是继承的。 Grails(和其他 Java 框架)通过操作字节码在运行时生成这些方法来解决这个问题。

    使用 groovy,在程序启动时,您可以尝试遍历所有 ActiveRecord 子类和 attaching the static finders to their meta class。如果您使用 ActiveRecord 类来查找子类并获取静态查找器,至少您仍然可以通过查看 ActiveRecord 类本身来判断它们继承了哪些方法。

    编辑:

    我想到你也可以在 ActiveRecord 类上实现 methodMissing 来尝试在 ActiveRecord 对象上查找方法。您只需要小心不要设置无限循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      • 2011-09-28
      • 1970-01-01
      • 2012-06-14
      • 2010-10-16
      • 1970-01-01
      相关资源
      最近更新 更多