2012-05-29 196 views
0

我正在修改打開的JDK來添加功能,我遇到過兩次沒有好的解決方案。如何從泛型子類轉換爲父類泛型的List?

有一個類名爲JCStatement其延伸JCTree

問題:我想將List<JCStatement>轉換爲List<JCTree>

很明顯,一個類可以引用它的一個擴展,但是當我把它放在List上時,它就不起作用。

我使用了:(List<JCTree>)((List<?>)params)來投射,它可以工作,但不會建立在螞蟻上。 IDE給我以下警告:

Type safety: Unchecked cast from List<capture#1-of ?> to List<JCTree> 

所以這必須以某種方式解決。

我很感激任何幫助。

+0

你不能使用類型轉換,也有方法可以幫助你,例如'Collections.copy(DEST名單,名單SRC)'。找到這些方法並選擇最適合你的方法。對不起,這個時候找不到他們 – alaster

+0

我編輯了這個文件來刪除額外的例子,這是不必要的,並清除標題問題。 –

+0

alaster,你的解決方案几乎可以工作,但我需要一種方法來實例化具有足夠空間的'List '副本,List.nil()不起作用。 – Adriano

回答

1

這似乎是列表或一般類型集合的問題。

簡單的解決方案永遠

ListBuffer<JCTree> ls = new ListBuffer<JCTree>(); 
for(JCVariableDecl v : params){ ls.append(v); } 
return ls.toList(); 
1

會這樣的工作嗎?

import java.util.ArrayList; 
import java.util.List; 

class A { 
} 

class B extends A { 
} 

class C extends A { 
} 

public class Program { 
    public static void foo(List<? extends A> list) { 
    } 

    public static void main(String[] args) { 
     List<A> listA = new ArrayList<A>(); 
     List<B> listB = new ArrayList<B>(); 
     List<C> listC = new ArrayList<C>(); 
     List<? extends A> listX = (List<? extends A>) listB; 
     List<? extends A> listY = (List<? extends A>) listC; 

     foo(listA); 
     foo(listB); 
     foo(listC); 
     foo(listX); 
     foo(listY); 
    } 
} 
+0

沒有,更有甚者: '方法appendList(名單)在類型ListBuffer 是不適用的參數(名單<?捕獲#2- \t延伸JCTree>)' – Adriano

+0

噢,對不起,我沒有意識到你在這種情況下對方法簽名沒有任何控制權。我的代碼示例將工作,如果你能夠改變方法簽名接受一個'List <?擴展JCTree>'而不是'列表'。我會在這裏留下這個答案*以防萬一*某人發現它有幫助。 –

2

您不能進行此演員表。

如果您將List<JCStatement>轉換爲List<JCTree>,然後將JCTree(非JCStatement)對象添加到該列表中,會發生什麼情況?它打破了List<JCStatement>類型的安全。

+0

+1爲清晰起見進行了編輯。如果OP解釋他爲什麼認爲這是解決方案,我們可以嘗試幫助他找到更好的解決方案。他沒有提供足夠的信息讓我們知道如何解決問題。 –

+0

我應該插入列表中沒有其他對象,添加一個可能會破壞編譯器。 – Adriano

0

你可以做到這一點,如果你真的真的相信它是安全的通過原始類型

List<Number> listA = new LinkedList<Number>(); 
List<Integer> listB = new LinkedList<Integer>(); 
listA = (List<Number>)(List) listB; 

鑄造我無法想象自己曾經以爲這是一個很好的解決了一個問題,但它會做什麼你想要編譯時間仿製藥有一些令人生氣的限制:)

對於不安全的演員,總是會有警告,因爲你所做的事實際上是不安全的。編譯器無法保證安全,您必須自己確定。

2

如果你知道你不會添加任何元素到列表中 - 所以它將是類型安全的 - 那麼Collections.unmodifiableList(List<? extends E>)將返回一個List<E>

這是完全類型安全且合法的,因爲它強制保證您永遠不會向列表中添加非法元素,並且它是由JDK提供的。