【问题标题】:Java Generics : Exception in Using Wildcards [duplicate]Java 泛型:使用通配符时的异常 [重复]
【发布时间】:2021-08-20 08:08:23
【问题描述】:

我有 2 个使用通用通配符链接的类

    import java.util.*;
    public class Main
    {
        public static void main(String[] args){
            AnotherClass another = new AnotherClass();
            List<Integer> a1 = new ArrayList<Integer>();
            a1.add(1);
            another.runtest(a1);
        }
        
    }
    import java.util.*;
    public class AnotherClass {
        public void runtest(List<? extends Number> a){
            a.add(2);
        }
    }

但在执行上述代码时,我遇到如下异常:

    AnotherClass.java:4: error: no suitable method found for add(int)
            a.add(2);
             ^
        method Collection.add(CAP#1) is not applicable
          (argument mismatch; int cannot be converted to CAP#1)
        method List.add(CAP#1) is not applicable
          (argument mismatch; int cannot be converted to CAP#1)
      where CAP#1 is a fresh type-variable:
        CAP#1 extends Number from capture of ? extends Number
    Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
    1 error

有人可以帮助我以更好的方式编写代码,或者我们如何在方法调用期间使用通配符。我无法理解为什么它现在允许在方法定义中扩展。

【问题讨论】:

  • 请从代码围栏中删除您的第一行。
  • @BenjaminM 非常感谢您的参考。它解决了我所有的疑惑。 :)
  • List&lt;? extends Number&gt; 是一个列表,其中包含 Numbersome 子类的 some ok 实例 - 很明显,你不知道是哪个。它可能是List&lt;Integer&gt;List&lt;Double&gt;,甚至是List&lt;MyCustomImplementationOfNumber&gt;。因此,编译器不知道添加Integer 是否安全。

标签: java generics


【解决方案1】:

List&lt;? extends Number&gt; 是一个列表,其中包含 Numbersome 子类的实例 - 重要的是,你不知道是哪个。可能是List&lt;Integer&gt;List&lt;Double&gt;,甚至是List&lt;MyCustomImplementationOfNumber&gt;

例如,List&lt;Double&gt; 应仅包含 Double(或 null)的实例。如果允许您在此方法的该列表中添加Integer,您将违反对Double 后续内容的预期。

编译器不知道向其添加Integer 是否安全。

解决方法是传递一个已知可以安全添加整数的列表。以下任何一项都可以(除其他外):

public void runtest(List<Integer> a){
public void runtest(List<Number> a){
public void runtest(List<? super Integer> a){
public void runtest(List<? super Number> a){

超界(界)说“我不知道类型的确切界线;但我知道它是一些超类”。由于子类的所有实例都是超类的实例,因此将子类的实例添加到列表中是安全的,因此是允许的。

【讨论】:

    【解决方案2】:

    理想情况下,在这样的代码中,您希望读取列表中的数据并对其采取行动,可能是删除项目,而不是通过添加项目来修改列表,因为您会遇到上述问题,因为代码不能保证自动装箱整数类型可以添加到列表中,因为它也可以是ArrayList&lt;Double&gt;

    如果您想修改列表,您需要针对特定​​类型的数字,例如 Integer 或 Double 或 Float 等......

    简而言之,我的建议是,使用这样的结构来读取/过滤/拆分/删除,而不是添加项目。

    【讨论】:

      猜你喜欢
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-22
      • 2015-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多