【问题标题】:java method is not applicable for the argumentsjava 方法不适用于参数
【发布时间】:2018-07-19 12:00:35
【问题描述】:

我不明白为什么 size(test); 无法编译。谁能帮我理解一下?

public class TestContainer<T extends Object> {
}

.

public class Main {
    public static int size(List<TestContainer<?>> list) {
        return list.size(); 
    }

    public static void main(String[] args) {
        List<TestContainer<Object>> test = new ArrayList<TestContainer<Object>>();
        size(test); // this does not compile
        test.size(); // of course this works fine
    }
}

【问题讨论】:

  • 编译器可能已经告诉你了。
  • 让它size(List&lt;? extends TestContainer&lt;?&gt;&gt;)
  • 或者这个大小(List> list)

标签: java generics arguments wildcard


【解决方案1】:

List&lt;TestContainer&lt;Object&gt;&gt; 不是List&lt;TestContainer&lt;?&gt;&gt;

TestContainer&lt;Integer&gt;TestContainer&lt;?&gt;。因此,您可以将TC&lt;Integer&gt; 添加到List&lt;TC&lt;?&gt;&gt;。同样,您可以将TC&lt;String&gt; 添加到List&lt;TC&lt;?&gt;&gt;

但是,TC&lt;Integer&gt; 不是 TC&lt;Object&gt;(因为泛型在 Java 中是不变的),因此您不能将 TC&lt;Integer&gt; 添加到 List&lt;TC&lt;Object&gt;&gt;。因此,List&lt;TC&lt;Object&gt;&gt; 不是 List&lt;TC&lt;?&gt;&gt;

如果你这样做是因为你无法在列表中添加任何东西(除了文字 null)——通过设置方法参数List&lt;? extends TC&lt;?&gt;&gt;(或List&lt;?&gt;,如果你真的对元素不感兴趣)——它是安全,因此被允许。

【讨论】:

    【解决方案2】:

    仅当List 参数声明使用上限通配符参数化时,具有泛型List 作为参数的方法才能接受泛型类型的子类。

    您没有在这里为List&lt;TestContainer&gt; 声明任何upper bounded wildcard (&lt;? extend T&gt;):

    public static int size(List<TestContainer<?>> list) {
        return list.size(); 
    }
    

    所以你只能将这个确切的类型作为参数传递:

    List<TestContainer<?>>
    

    要实现你想要的,你应该这样写:

    public static int size(List<? extends TestContainer<?>> list) {
        return list.size(); 
    }
    

    请注意,上限通配符旨在确保传递的 List 的类型安全。
    因此,在方法内部,除了null,您无法添加任何内容。
    但是对于您的用例(返回列表的大小),这不是问题。

    【讨论】:

      猜你喜欢
      • 2015-12-20
      • 2019-04-04
      • 1970-01-01
      • 1970-01-01
      • 2012-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多