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”的消息
# 1 楼答案
Groovy不是静态类型的。我想你会发现它会在编译时删除T,甚至不用费心去计算它不在范围之内;这与Groovy无关
# 2 楼答案
您将遇到的主要问题是,在Java和Groovy中,静态方法不会被继承。Grails(和其他Java框架)通过在运行时操作字节码来生成这些方法来解决这个问题
使用groovy,在程序启动时,您可以尝试遍历所有ActiveRecord子类和attaching the static finders to their meta class。如果您使用ActiveRecord类来查找子类和静态查找程序,那么至少您仍然可以通过查看ActiveRecord类本身来判断它们继承了哪些方法
编辑:
我突然想到,您也可以在ActiveRecord类上实现methodMissing,以尝试在ActiveRecord对象上查找该方法。您只需小心不要设置无限循环