2013-12-11 49 views
3

有沒有什麼辦法可以在運行時創建泛型類型的特定實例?Java泛型 - 我可以根據變量類型動態創建列表

例如。

Cacheable instance = getCacheable(someInput); 

getCacheble方法將返回Cacheable的實例。所以它可以是任何實現Cacheable的類,例如客戶,產品等。現在我想創建一個由getCacheable返回的特定類型的列表,如下所示。這可能嗎?如果是的話該怎麼做?

List<? extends Cacheable> cacheList = new ArrayList<>(); 

我想根據getCacheable方法返回的實例創建ArrayList<Product> or ArrayList<Customer>

+1

由於力擦除這有點不合理,因爲名單沒有按在運行時沒有類型。泛型是用於編譯時檢查。所以真正的答案取決於你的實際使用情況。你爲什麼要編譯時間檢查和如何?在運行時,你可以把任何東西放在任何列表中,泛型只是作爲看門人。 – Radiodef

回答

6

你可以這樣做:因爲類型擦除

Cacheable instance = getCacheable(someInput); 
List<? extends Cacheable> l = new ArrayList<>(); 
l = Collections.checkedList(l, instance.getClass()); 

,在編譯時訪問的所有信息在運行時丟失。 checkedList方法將確保您的列表將只接收instance變量類的實例。

UPDATE: 你也可以這樣做:

public static <T extends Cacheable> MyOwnCustomGeneric<T> createMyOwnCustomGeneric(Class<T> type) { 
    return new MyOwnCustomGeneric<T>(); 
} 

// ... 
IMyOwnCustomGeneric foo = createMyOwnCustomGeneric(instance.getClass()); 
+0

感謝您的回答。問題是我實際上並沒有使用List,它是我自己的自定義泛型類。我以List作爲示例來簡化prob語句。 – JRR

+0

@Jai你自己定製的泛型類是一個'Collection'(http://docs.oracle.com/javase/7/docs/api/java/util/Collection.html)?如果是這樣,你可以使用'checkedCollection'而不是'checkedList'。 – Stephan

+0

否Alex.Its不收集。我想在這裏避免支票的實例,但我認爲它不可能。 – JRR

0
if (instance instanceof Product) { 
    // create ArrayList<Product>; 
} else { 
    // create ArrayList<Customer>; 
} 

這是不是真的一般,動態不過。

+1

但我更喜歡Alex的回答。 –

0

做到這一點的唯一方法是通過對instance類型的開關,但沒有太多,你可以用它做:

List<? extends Cacheable> cacheList = null; 
if (instance instanceof Product) 
    cacheList = new ArrayList<Product>(); 
// etc 

但是你能對這個名單嗎?你不能添加任何東西。也許你在創建它時添加了項目,但這可能不是用例,因爲它是一個緩存列表。

如果您需要稍後添加項目,請參閱this answer是正確的方法。

如果你不打算在以後添加的項目,它不一樣,如果類型是List<Cacheable>List<? extends Cacheable>重要

2

使用通用的輔助功能:

public static <T extends Cacheable>ArrayList<T> createList(Class<T> claz) 
{ 
     return new ArrayList<>(); 
} 

ArrayList<? extends Cacheable>alist = createList(instance.getClass()); 
+0

請注意,參數'claz'沒有使用,可以刪除。 –

+0

@PaulBellora,是不是需要從實例自己的類型推斷出類型。我明白,因爲'alist'的類型是'ArrayList <?擴展Cacheable>'不需要 – Sage

+0

類型推斷是在編譯時發生的事情。如果失敗,可以用例如手動指定類型參數。 'MyClass的。 createList()'。但考慮到泛型在運行時已經被擦除,OP所要求的是沒有意義的。 'createList(instance.getClass())'可以簡化爲'new ArrayList ()',因爲在運行時它只是'ArrayList'。 –