为什么我不能使用通配符(?)作为参数,字段,局部变量的类型,或作为方法的返回类型?

Sol*_*ace 14 java generics wildcard bounded-wildcard unbounded-wildcard

关于泛型中的通配符的Oracle 文档说,

通配符可用于各种情况:作为参数,字段局部变量的类型 ; 有时作为返回类型 (虽然更好的编程实践更具体).

我在下面的类中尝试了所有四个,并且在每个类中都有编译器错误.为什么?我究竟做错了什么?

public class MainClass {
    private ? instanceFieldWithWildCardType;//ERROR
    private static ? staticFieldWithWildCardType;//ERROR

    private void methodWithWildCardParam(? param) {}//ERROR

    private void methodWithWildCardLocalVariable() {
        ? localVariableWithWildCardType;//ERROR
    }

    private ? methodWithWildCardReturnType() {//ERROR
        return null;
    }

    private void methodWithWildCardParam(? param) {}//ERROR

}
Run Code Online (Sandbox Code Playgroud)

Sot*_*lis 9

?字符是通配符类型参数.

文章开头

在通用代码中,称为通配符的问号(?)表示未知类型.

您可以使用该语法的唯一地方是通用代码的一部分,即.泛型类型参数.下一句是指使用通配符的通用代码.所以,例如

作为参数的类型

你可以有

public static void shuffle(List<?> list) {
Run Code Online (Sandbox Code Playgroud)

或者

作为局部变量

public void method() {
    List<?> list = Arrays.asList(1, 2, 3);
    Collections.shuffle(list);
    System.out.println(list);
}
Run Code Online (Sandbox Code Playgroud)

通配符从不用作泛型方法调用,泛型类实例创建或超类型的类型参数.

你不能用它

Arrays.<?>asList(1, "", '5');
List<?> list = new ArrayList<?>();
...
public class MyList implements List<?> {/* whatever */}
Run Code Online (Sandbox Code Playgroud)


use*_*ica 9

该教程非常明确.您不能对列出的任何内容使用通配符.您可以在其中使用带有通配符的泛型类型.

public class Example {
    ? field1;        // invalid
    List<?> field2;  // valid

    private ? method1(? param) {return param;}              // invalid
    private List<?> method2(List<?> param) {return param;}  // valid

    private void method3() {
        ? var1;        // invalid
        List<?> var2;  // valid
    }
}
Run Code Online (Sandbox Code Playgroud)