繁体   English   中英

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

[英]Why can't I use the wildcard (?) as type of parameter, field, local variable, or as return type of a method?

关于泛型中的通配符的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

}

? character是通配符类型参数

文章开头

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

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

作为参数的类型

你可以有

public static void shuffle(List<?> list) {

或者

作为局部变量

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

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

你不能用它

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

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

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
    }
}

在java 5中引入的泛型概念中,通配符可与<>运算符一起使用, 用于表示未知类型 泛型用于定义具有通用格式成员的类。如果要在创建对象时提供工具,用户将指定成员的类型,然后您可以使用泛型的概念。 它只能用于实例成员不能与静态成员一起使用,因为静态内存只会被分配一次。

在泛型中引入的通配符概念用于限制未知类型,假设我有一个带有通配符的列表,这个通配符扩展了数字包装类。 这意味着列表可以使用Integer,Long,Short,Byte,因为它们扩展了Number包装类,但没有使用String作为String类,不扩展Number包装类。

List<? extends Number> lt = new ArrayList<>();

来到你的程序,你使用了错误的语法,因为我已经提到过通配符可以与<>运算符一起使用。

我们不能在实例化上面提到的类时使用通配符 -

 List<?> lt = new ArrayList<?>();

但我们可以使用泛型来提供字段作为员工类中的I,N,S等未知类型。 这是我们在创建类的对象时将提供的类型 -

class Employee<I,N,S>
{
    I eid;
    N empName;
    S empSalary;
}

class Name
{
   String firstName;
   String middleName;
   String lastName;
}

class salary
{
    double basic;
    float it;
    float tds;
    double netsal;
}

class CustomId
{
   int empId;
   String department;
   int branchId;
} 

main method 
------------

    Employee<Integer,String,Double> emp = new Employee<>();
    Employee<String,Name,Salary> emp2 = new Employee<>();
    Employee<CustomId,String,Salary> emp3 = new Employee<>();

通配符作为方法参数 -

public void sortList(List<?> lt)
{
   // code to sort the list whether it is integer, String etc
}
call sortList() method
-----------------------
List<String> lt = new List<>();
lt.add("sss");
lt.add("aaa");
sortList(lt);

List<Integer> lt = new List<>();
lt.add(11);
lt.add(12);
sortList(lt);

将局部变量声明为通配符 -

 List<?> lt = new ArayList<String>();
 List<?> lt = new ArayList<Integer>();

我们可以使用通配符和泛型作为返回类型的方法。 以下是泛型作为返回类型方法的示例 -

public T getName(ClassName obj, Key key)
{
    return (Type<T>)obj.getType(Key);
}

以下是通配符作为返回类型方法的示例 -

    List<?> method(List<?> data) 
    {
        return data;    
    }

通配符没有个人存在。 它们总是用作Generic类Ex: List<? extends Number>类型参数List<? extends Number> List<? extends Number> 。我举一个涵盖所有场景的例子。

import java.util.ArrayList;
import java.util.List;

class A{

    // I have not make use of this anywhere in this example
    List<? extends Number> l1; //Field;

    //Just taking l2 as parameter
    //Wont be using it also
    //Just tp show wildcard with generic as parameter
    public List<? extends Number> operate(List<? extends Number> l2){ //As return Type; Not recommended Approach

        List<Integer> list = new ArrayList<>();
        list.add(new Integer(6));
        return list;
    }

}



public class Main {

    public static void main(String[] args) {

        List<? extends Number> ar = new ArrayList<Integer>(); //Local Variable
        A obj = new A();
        System.out.println(obj.operate(ar));
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM