【问题标题】:What is concept behind CAP#1 in generic (wild-card) JAVA?通用(通配符)JAVA 中 CAP#1 背后的概念是什么?
【发布时间】:2016-07-19 04:04:15
【问题描述】:

考虑以下示例:

class First<T >
{
  T s;
  First(T s)
  {
        this.s=s;
  }
  void setS(T s)
  {
        this.s=s;
  }
  void getS()
  {
    System.out.println(s);
  }
}

class Use
{
        public static void setFirst(First<?>f)
        {
                f.setS(7);
        }
        public static void main(String[] args)
        {
                First <Integer> f4 = new First<Integer>(5);
                f4.getS(); 
                setFirst(f4);                   
        }
}

我知道编译器会报错,因为在形式参数使用泛型通配符的方法中不允许写入特定操作。编译错误是:

gyan@ns:~/codes/java/generics$ javac -Xdiags:verbose *.java
Use.java:5: error: method setS in class First<T> cannot be applied to given types;
        f.setS(7);
         ^
  required: CAP#1
  found: int
  reason: argument mismatch; int cannot be converted to CAP#1
  where T is a type-variable:
    T extends Object declared in class First
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?
1 error
gyan@ns:~/codes/java/generics$ 

看起来 CAP#1 是一种数据类型。我对这个概念一无所知。请帮忙。

【问题讨论】:

标签: java generics parameter-passing wildcard


【解决方案1】:

这里的问题是&lt;?&gt; 表示未知类型,即List&lt;?&gt; 表示未知类型的列表,因此除了 null 之外什么都不能添加,因为编译器无法验证添加时的类型。

但是,您可以将参数类型更改为 &lt;Integer&gt;&lt;? super Integer&gt; 以使该方法起作用:

public static void setFirst(First<Integer> f) {
    f.setS(7);
}

参考:wildcards in generics

【讨论】:

    【解决方案2】:

    在泛型中,所有内容都在编译时被替换以提供类型安全。

    在您的示例中,编译器将f 输入参数处理为Object 类型。当setFirst(First&lt;?&gt;f) 方法调用f.setS(7); 时,编译器无法确认正在初始化的对象类型并产生错误。

    当发生这种类型的错误时,通常意味着编译器认为您将错误的类型分配给变量。 Java 语言中添加了泛型,以在编译时强制执行类型安全。

    public static void setFirst(First<?>f) // at compile time no special type parameter found. So No Replacement will take place.
            {
                    f.setS(7); //confusing case because it not a type Parameter should be replace with any Java Class not the Constant.
            }
    

    但在其他情况下在 main

    First <Integer> f4 = new First<Integer>(5); // T is replaced with Integer.
     f4.getS(); // It will produce 5
     setFirst(f4);  // it will also get executed because of f4 is a object of First<Integer>.
    

    【讨论】:

      猜你喜欢
      • 2012-03-20
      • 2012-04-17
      • 1970-01-01
      • 2011-01-15
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多