2010-10-09 215 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的對象,而不是對方法。你只需要小心不要設置無限循環。