在Main中的非泛型定义类中调用泛型方法

时间:2013-10-26 00:33:11

标签: java generics

我有一个类GraphSearch,定义如下:

public class GraphSearch{
///code
}

在这个类中是泛型参数化方法:

public static <T> int dsp(T start, Map<T, List<Pair<T, Integer>>> adjList, T goal) {
///code}

我有一个主要的我做这个设置并调用方法:

GraphSearch g = new GraphSearch();
HashMap<String,ArrayList<Pair<String,Integer>>> k = new  HashMap<String, ArrayList<Pair<String, Integer>>>();
////various setup to fill my map with valid stuff
///Pair is a class I made in my package

然后在主要是

System.out.println("dsp from A to E is" + g.dsp("a", k, "e"));

我收到错误。

The method dsp(T, Map<T,List<Pair<T,Integer>>>, T) in the type GraphSearch is not applicable for the arguments (String, HashMap<String,ArrayList<Pair<String,Integer>>>, String)

好吧,为什么不呢? ArrayList不是List吗?字符串不是通用可接受的类型吗? Hashmap不是Map吗?

发生了什么事?

2 个答案:

答案 0 :(得分:3)

这里的问题很微妙,但它的基础是in Java generics, a Type<A> is not a Type<B>, even if A extends B。在此,AArrayListBList

您定义了HashMap<String,ArrayList<Pair<String,Integer>>>,但您的方法需要Map<String,List<Pair<String,Integer>>>。尝试使用k而不是List定义ArrayList,它应该有效:

HashMap<String,List<Pair<String,Integer>>> k =
    new HashMap<String, List<Pair<String, Integer>>>();

或者定义dsp方法以使用ArrayList代替:

public static <T> int dsp(T start, Map<T, ArrayList<Pair<T, Integer>>> adjList, T goal) {

此外,即使允许,您也应该通过类的实例访问静态方法,例如dsp。为清晰起见,最好使用类名访问它:

// GraphSearch.dsp instead of g.dsp.
System.out.println("dsp from A to E is" + GraphSearch.dsp("a", k, "e"));

答案 1 :(得分:3)

因为Map<T, ArrayList<...>> Map<T, List<...>>的子类型。请参阅this thread(以及其他内容)了解原因。

如果您想支持该用例,您的通用应为Map<T, ? extends List<Pair<T, Integer>>>

另一种方法是将k更改为Map<String,List<Pair<String,Integer>>>类型 - 即使您使用? extends语法,这也是首选,因为它允许您program to the interfaces并更好地使用多态。例如,如果您以后决定值应为k而不是LinkedList,则无需更改ArrayList