2013-03-11 73 views
1

我敢肯定這是一個重複的,但我的搜索關鍵字太常見了...我得到了很多點擊,我沒有找的東西。我來自C#,Java泛型似乎稍微落後於.NET實現,所以這對我來說非常令人沮喪。呼叫基礎構造函數與不同的參數比子類的構造函數

我有一個抽象類BaseRepository像這樣:

public abstract class BaseRepository<T, K> implements Repository<T, K> { 

    private Class<T> type; 
    private Class<K> keyType; 

    public BaseRepository(Class<T> clazz, Class<K> kClazz) { 
     type = clazz; 
     keyType = kClazz; 
    } 

    protected Class<T> getType() { 
     return type; 
    } 

    protected Class<K> getKeyType(){ 
     return keyType; 
    } 
} 

現在我想從我的基類派生與EmployeeRepository像這樣:

public class EmployeeRepository extends BaseRepository<Employee, UUID>{ 

} 

用c#,我就不需要做這樣的英雄努力來實例化基類,但似乎Java的泛型實現要求您在構造函數中傳遞泛型類型。

那麼如何爲我的EmployeeRepository類創建一個無參數構造函數,該類實例化基類的實體類型爲Employee,密鑰類型爲UUID?我希望能夠寫這篇文章:

EmployeeRepository foo = new EmployeeRepository(); 

...,並將它實例化抽象類Class<Employee>Class<UUID>

+0

你爲什麼要到有「型」和「關鍵字類型」字段? – Fortega 2013-03-11 15:18:33

+0

我需要引用基類的其他方法中的類型。 – 2013-03-11 15:19:31

回答

6

據我所知,沒有辦法全面超越從默認的子類構造函數調用父類的構造因而這個其他:

public EmployeeRepository() { 
    super(Employee.class, UUID.class); 

    ... 
} 
+0

......看起來很有希望。我不知道你可以這樣做。 – 2013-03-11 15:21:12

+0

+1不需要英勇的努力 – tjameson 2013-03-11 15:24:02

+0

這工作,而且很容易實現。謝謝! – 2013-03-11 15:34:10

1

你可以使用反射來確定的一般參數的類型。

public abstract class BaseRepository<T, K> implements Repository<T, K> { 

    private Class<T> type; 
    private Class<K> keyType; 

    public BaseRepository() { 
     Type[] actualTypes = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments(); 
     this.type = (Class<T>)actualTypes[0]; 
     this.keyType = (Class<K>)actualTypes[1]; 
    } 

    protected Class<T> getType() { 
     return type; 
    } 

    protected Class<K> getKeyType(){ 
     return keyType; 
    } 
} 

但是,真正的問題是:爲什麼你想要的類型?

+0

爲什麼需要類對象可能有很多原因。最有可能的是,需要從泛型基類內部構造類的新實例。 – 2013-03-11 15:24:28

+0

我的基礎知識庫類中有幾個方法需要實體的類類型作爲參數。從我讀過的內容來看,反思一般都是爲這種事情而皺起了眉頭,儘管我不知道爲什麼。與Oli的回答相比,這樣做有沒有優勢/劣勢? – 2013-03-11 15:26:40

+0

這種方法需要一些工作才能正常運行(例如,您不能將'Type'分配給'類',如果我們要創建子子類,這將不起作用)。 – 2013-03-11 15:33:53

0

作爲替代,使用Builder模式:

public class EmployeeRepository extends BaseRepository<Employee, UUID>{ 
    public static EmployeeRepository newInstance() { 
     return new EmployeeRepository(Employee.class, UUID.class); 
    } 
    ... 
} 

EmployeeRepository foo = EmployeeRepository.newInstance(); 
+0

你仍然需要一個子類ctor才能將這些參數傳遞給超類ctor,但是...... – 2013-03-11 15:25:24

+0

當然,但它有助於隱藏實現細節。你也可以使基類(和子類)的構造函數受到保護。 – 2013-03-11 15:26:46