有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Groovy静态泛型类型

我一直在努力摆脱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编译器正在用生成的Java类中的实际类名替换T

在严格意义上的Java中,我可以从find方法返回类型和类声明中访问泛型类型,但这两种类型都被擦除为对象。这是有道理的,Groovy也这样做,但在Java中,上面的行错误会显示一条类似于“Cannotreferencenonstatict”的消息


共 (2) 个答案

  1. # 1 楼答案

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

  2. # 2 楼答案

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

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

    编辑:

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