2011-08-01 40 views
41

在我的Java代碼中,我經常使用非常方便的可變參數method(Class... args)。據我所知,它們允許您通過任何數量的Class對象或Class[]陣列。由於我也經常使用Java集合類,所以我對兩者之間缺乏兼容性感到沮喪。因此,我最終做了collection.toArray(),但這有一些類型安全問題。Java可變參數爲什麼不支持集合?

因此,現在的問題是:爲什麼Java不允許Iterable<T>的實例作爲可變參數,只要泛型類型符合可變參數的T...類型?不是每個人都一直使用列表,集合等嗎?是否有一種簡單的,類型安全的方法來提供從收集到可變參數的轉換?

回答

48

原因很簡單:一個可變的參數參數只是一個老派的參數,它帶有一些額外的元數據,告訴編譯器提供一些語法糖(即允許隱式數組創建)。

所以從JVM的角度來看Object...Object[]差不多。允許集合也需要對JVM進行更多入侵式更改(迄今爲止對集合沒有明確的支持)。

注意,如果你想支持兩種方式,則使基於集合的方法可能是更好的方法:

public void frobnicate(Object... args) { 
    frobnicate(Arrays.asList(args)); 
} 

public void frobnicate(Iterable<Object> args) { 
    // do stuff 
} 

這樣做的原因是,使用Arrays.asList()通常一個操作較便宜Collection.toArray()(因爲它創建了一個簡單的包裝)。

+0

它從技術角度回答了這個問題,但作爲一名開發人員,我仍然認爲只要我想使用集合和普通對象就提供一個輔助方法是很愚蠢的。當然,與幾年前相比,我們擁有收藏品和可變參數的事實已經是一種解脫。 – tb189

+3

@精英紳士:我只是喜歡用'frobnicate'而不是簡單的'foo'。 [源(http://www.catb.org/jargon/html/F/frobnicate.html)。 –

+0

@ tb189:爲什麼一個「幫手法」?你想要一個方法來接受兩種不同的,類型無關的參數。這正是*超載旨在處理的問題。 –

相關問題