2010-10-09 176 views
0

我一直在玩摆脱DAO赞成ActiveRecord像Java中的实体,但泛型不会让我有我想要的全部功能(如静态发现者)。不知何故,Groovy确实如此,但我很困惑。鉴于以下几点: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中,我可以从查找方法返回类型和类声明中访问泛型类型,但两者都被擦除为Object。这是有道理的,而Groovy也是这样,但在Java中,上面的行错误带有类似'不能引用非静态T'的消息。

回答

2

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

+0

很高兴知道!我没有做太多的groovy开发。看起来我需要多读一点。 – hisdrewness 2010-10-14 06:28:53

1

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

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

编辑:

它发生,我认为你也可以实现在ActiveRecord类methodMissing试图寻找在ActiveRecord的对象,而不是对方法。你只需要小心不要设置无限循环。