2015-11-10 66 views
3

假設我有類:的Java:如何以小博大的嵌套泛型類型

public interface ObjectWithId<T> { 
    T getId(); 

    void setId(T id); 
} 

public class BaseDBObject<T> implements ObjectWithId<T> { 
    // Common fields: 
    private T id; 
    private String createdBy; 
... 
} 

而且一個具體:

public class ConstituentEntity extends BaseDBObject<Integer> { 
... 
} 

然後,我創建了一些服務,這不能不還採取? extends BaseDBObject通用的參數之一,在某些方法中應該使用適當類型的id。 現在,它採用雙泛型實現:

abstract public class BaseService<IdT,T extends BaseDBObject<IdT>> { 
    public T getById(IdT id){ 
     return getDao().getById(id); 
    } 
} 

public class ConstituentEntityService extends BaseService<Integer, ConstituentEntity>{ 
... 
} 

但在最後一個定義再看看。我知道ConstituentEntity已經有Integer作爲他們的鑰匙持有人,所以我再次提供這種類型的服務似乎很難看。

我看一些可能性來寫未來建設:

abstract public class BaseService<T extends BaseDBObject> { 
    public T getById(??T.T?? id){ 
     return getDao().getById(id); 
    } 
} 

在C++中,我們有typenametypedef對於這樣的情況有其複雜而強大的元編程的可能性。 Java中可能有類似的東西嗎?

+0

也許不是最好的評論,但是:通常,Java泛型是不可避免的醜陋。你只需要吸他們。我已經完成了與「雙重泛型」完全相同的操作。 –

回答

2

我想,這是不可能的。如果您有使用IntegerT多的服務,那麼你可以定義中級班:

public abstract class IntegerService<S extends BaseDBObject<Integer>> 
            extends BaseService<Integer, S>{ 
    ... 
} 

並使用public class ConstituentEntityService extends IntegerService<ConstituentEntity>。但是,如果有許多不同的類型用作T,那麼每個T類型都必須這樣做。

+0

這可能是(醜陋的)問題的解決方法。除了兩個泛型類型,它將隱藏在下一個層次結構中。 Meantyme它有幾個缺點。首先(由你提到) - 爲任何類型創建中間類。其次,它只是實現類而看起來像垃圾。最後,在任何使用它的地方(不僅服務需要它,驗證器,助手等等),這個數字將會爆炸增加。 – Hubbitus

+0

@Hubbitus,這就是爲什麼我以「這是不可能的」開始我的答案。我也不喜歡我的解決方案。 –