2012-05-29 160 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提供的。