![](/img/trans.png)
[英]Why can't a nested wildcard be assigned to a variable with a type parameter?
[英]Why can't I use the wildcard (?) as type of parameter, field, local variable, or as return type of a method?
通配符可用于各种情况:作为参数 , 字段或局部变量的类型 ; 有时作为返回类型 (虽然更好的编程实践更具体)。
我在下面的类中尝试了所有四个,并且在每个类中都有编译器错误。 为什么? 我究竟做错了什么?
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.