我有一个采用SResource对象列表的方法

public static List<STriple> listTriples(List<SResource> subjects){
//... do stuff
}

我为什么不能这样做
List<IndexResource> resultsAsList = new ArrayList<IndexResource>();
    resultsAsList.addAll(allResults.keySet()); // I could possible not use lists and just use sets and therefore get rid of this line, but that is a different issue
List<STriple> triples = new ArrayList<STriple>();
    triples = TriplesDao.listTriples(resultsAsList);

(编译器告诉我,我必须使triples使用SResource对象。)

当IndexResource是SResource的子类时
public class IndexResource extends SResource{
// .... class code here
}

我本以为必须做到这一点,所以也许我在做其他错误的事情。如果您建议,我可以发布更多代码。

最佳答案

您可以使用wildcards做到这一点:

public static List<STriple> listTriples(List<? extends SResource> subjects){
    //... do stuff
}

新的声明使用有界通配符,表示通用参数将是SResource或扩展它的类型。

作为以这种方式接受List<>的交换,“做东西”不能包括插入subjects。如果您只是从方法中的subjects中读取内容,那么此更改将为您提供所需的结果。

编辑:要了解为什么需要通配符,请考虑以下(在Java中是非法的)代码:
List<String> strings = new ArrayList<String>();
List<Object> objList = string; // Not actually legal, even though string "is an" object
objList.add(new Integer(3)); // Oh no! We've put an Integer into an ArrayList<String>!

那显然不是类型安全的。但是,使用通配符,您可以执行以下操作:
List<String> strings = new ArrayList<String>();
string.add("Hello");
List<? extends Object> objList = strings; // Works!
objList.add(new Integer(3)); // Compile-time error due to the wildcard restriction

07-24 14:55