0

我正在修改开放的 JDK 以添加功能,但我已经遇到了两次没有好的解决方案。

有一个名为JCStatementextends的类JCTree

问题:我想将 aList<JCStatement>转换为List<JCTree>.

很明显,一个类可以引用它的一个扩展,但是当我将它放在 List 上时,它就不起作用了。

我使用:(List<JCTree>)((List<?>)params)进行投射,它可以工作,但不能建立在 ant 上。IDE 给我以下警告:

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

所以这必须以某种方式解决。

我很感激任何帮助。

4

5 回答 5

2

如果您知道不会将任何元素添加到列表中——因此它将是类型安全的——那么Collections.unmodifiableList(List<? extends E>)将返回一个List<E>.

这是完全类型安全且合法的,因为它强制保证您永远不会将非法元素添加到列表中,并且它是由 JDK 提供的。

于 2012-05-29T17:10:09.000 回答
2

你不能做这个演员表。

如果将 aList<JCStatement>转换为 aList<JCTree>然后将 JCTree(非 JCStatement)对象添加到该列表会发生什么?它破坏了List<JCStatement>类型安全。

于 2012-05-29T16:32:08.453 回答
1

这似乎是 List 或泛型类型集合的问题。

有史以来最简单的解决方案:

ListBuffer<JCTree> ls = new ListBuffer<JCTree>();
for(JCVariableDecl v : params){ ls.append(v); }
return ls.toList();
于 2012-05-29T18:27:01.880 回答
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);
    }
}
于 2012-05-29T16:31:50.093 回答
0

如果你真的确定它是安全的,你可以通过 Raw Type 进行转换

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

我无法想象自己曾经认为这是解决问题的好方法,但它会做你想做的事,而且编译时泛型有一些令人讨厌的限制:)

总是会有一个 Unsafe 演员的警告,因为你所做的实际上是不安全的。编译器无法使其安全,您必须自己确定这一点。

于 2012-05-29T17:05:26.160 回答