【问题标题】:Calling Generic-Defined Method in a Non-Generic-Defined Class in Main在 Main 的非泛型定义类中调用泛型定义的方法
【发布时间】:2013-10-26 09:10:47
【问题描述】:

我有一个类,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 不是列表吗?字符串不是通用可接受的类型吗? Hashmap 不是 Map 吗?

发生了什么事?

【问题讨论】:

    标签: java generics


    【解决方案1】:

    这里的问题很微妙,但它基于in Java generics, a Type&lt;A&gt; is not a Type&lt;B&gt;, even if A extends B.这里,AArrayListBList

    您定义了HashMap&lt;String,ArrayList&lt;Pair&lt;String,Integer&gt;&gt;&gt;,但您的方法需要Map&lt;String,List&lt;Pair&lt;String,Integer&gt;&gt;&gt;。尝试用List 代替ArrayList 定义k,它应该可以工作:

    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"));
    

    【讨论】:

    • 哇...这很奇怪,我想。在我对这样一个对象的定义中,我可以用 Hashmap “替换” Map 而不是用 ArrayList 替换 List,这对我来说似乎并不直观。但也许我是从一个没有受过教育的角度看待它。
    • 这是违反直觉的。但认为 rgettman 和我提供的链接说明了为什么会这样。
    【解决方案2】:

    因为Map&lt;T, ArrayList&lt;...&gt;&gt; 不是Map&lt;T, List&lt;...&gt;&gt; 的子类型。请参阅this thread(以及其他)了解原因。

    如果您想支持该用例,您的泛型应为 Map&lt;T, ? extends List&lt;Pair&lt;T, Integer&gt;&gt;&gt;

    另一种选择是将k 更改为Map&lt;String,List&lt;Pair&lt;String,Integer&gt;&gt;&gt; 类型——即使您确实使用? extends 语法,这也是更可取的,因为它可以让您program to the interfaces 并更好地使用多态性。例如,如果您稍后决定值应该是 LinkedLists 而不是 ArrayLists,则不必更改 k

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-30
      • 1970-01-01
      • 2021-02-16
      相关资源
      最近更新 更多