为什么我不能将通配符 (?) 用作参数类型、字段、局部变量或方法的 return 类型?
Why can't I use the wildcard (?) as type of parameter, field, local variable, or as return type of a method?
Oracle doc about Wildcards in generics 说,
The wildcard can be used in a variety of situations: as the type of a
parameter, field, or local variable; sometimes as a return type
(though it is better programming practice to be more specific).
我已经尝试了以下所有四种 class,并且每一种都出现编译器错误。为什么?我做错了什么?
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
}
?
字符是 wildcard type argument。
文章开头为
In generic code, the question mark (?), called the wildcard,
represents an unknown type.
您唯一可以使用该语法的地方是作为通用代码的一部分,即。泛型类型参数。下一句是指使用通配符的通用代码。所以,例如
as the type of a parameter
你可以
public static void shuffle(List<?> list) {
或
as a local variable
public void method() {
List<?> list = Arrays.asList(1, 2, 3);
Collections.shuffle(list);
System.out.println(list);
}
但是
The wildcard is never used as a type argument for a generic method
invocation, a generic class instance creation, or a supertype.
您不能将其用作
Arrays.<?>asList(1, "", '5');
List<?> list = new ArrayList<?>();
...
public class MyList implements List<?> {/* whatever */}
通配符可以和<>运算符一起使用在泛型概念中引入java5,用于表示未知类型.泛型用于在广义 format.If 中定义一个 class 成员,你想提供便利,在创建对象时,用户将指定成员的类型,然后你可以使用泛型的概念。它只能用于实例成员,不能与静态成员一起使用,因为静态成员的内存只会分配一次。
泛型中引入的通配符概念来限制未知类型,假设我有一个包含通配符的列表,并且这个通配符扩展了 Number wrapper class。这意味着列表可以与 Integer、Long、Short、Byte 一起使用,因为它们扩展了 Number wrapper class 但不能与 String 一起使用,因为 String class 不扩展 Number wrapper class。
List<? extends Number> lt = new ArrayList<>();
来到你的程序,你使用了错误的语法,正如我提到的,通配符可以与 <> 运算符一起使用。
We can't use wildcard while instantiating class like mentioned bellow -
List<?> lt = new ArrayList<?>();
但我们可以使用泛型将字段提供为未知类型,例如员工 class 中的 I、N、S。这是我们在创建 class -
的对象时提供的类型
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<>();
Wildcard as method parameter -
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);
Declaring local variable as wildcard -
List<?> lt = new ArayList<String>();
List<?> lt = new ArayList<Integer>();
We can use wildcard and generics as return type of method.
Here is the example of generics as return type of method -
public T getName(ClassName obj, Key key)
{
return (Type<T>)obj.getType(Key);
}
这里是通配符的例子,作为return类型的方法-
List<?> method(List<?> data)
{
return data;
}
该教程措辞糟糕。您不能对列出的任何内容使用通配符。对于这些事情,您可以使用带有通配符的通用类型。
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
}
}
通配符没有单独的存在。它们总是用作泛型的类型参数 类 例如: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));
}
}
Oracle doc about Wildcards in generics 说,
The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific).
我已经尝试了以下所有四种 class,并且每一种都出现编译器错误。为什么?我做错了什么?
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
}
?
字符是 wildcard type argument。
文章开头为
In generic code, the question mark (?), called the wildcard, represents an unknown type.
您唯一可以使用该语法的地方是作为通用代码的一部分,即。泛型类型参数。下一句是指使用通配符的通用代码。所以,例如
as the type of a parameter
你可以
public static void shuffle(List<?> list) {
或
as a local variable
public void method() {
List<?> list = Arrays.asList(1, 2, 3);
Collections.shuffle(list);
System.out.println(list);
}
但是
The wildcard is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype.
您不能将其用作
Arrays.<?>asList(1, "", '5');
List<?> list = new ArrayList<?>();
...
public class MyList implements List<?> {/* whatever */}
通配符可以和<>运算符一起使用在泛型概念中引入java5,用于表示未知类型.泛型用于在广义 format.If 中定义一个 class 成员,你想提供便利,在创建对象时,用户将指定成员的类型,然后你可以使用泛型的概念。它只能用于实例成员,不能与静态成员一起使用,因为静态成员的内存只会分配一次。
泛型中引入的通配符概念来限制未知类型,假设我有一个包含通配符的列表,并且这个通配符扩展了 Number wrapper class。这意味着列表可以与 Integer、Long、Short、Byte 一起使用,因为它们扩展了 Number wrapper class 但不能与 String 一起使用,因为 String class 不扩展 Number wrapper class。
List<? extends Number> lt = new ArrayList<>();
来到你的程序,你使用了错误的语法,正如我提到的,通配符可以与 <> 运算符一起使用。
We can't use wildcard while instantiating class like mentioned bellow -
List<?> lt = new ArrayList<?>();
但我们可以使用泛型将字段提供为未知类型,例如员工 class 中的 I、N、S。这是我们在创建 class -
的对象时提供的类型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<>();
Wildcard as method parameter -
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);
Declaring local variable as wildcard -
List<?> lt = new ArayList<String>();
List<?> lt = new ArayList<Integer>();
We can use wildcard and generics as return type of method. Here is the example of generics as return type of method -
public T getName(ClassName obj, Key key)
{
return (Type<T>)obj.getType(Key);
}
这里是通配符的例子,作为return类型的方法-
List<?> method(List<?> data)
{
return data;
}
该教程措辞糟糕。您不能对列出的任何内容使用通配符。对于这些事情,您可以使用带有通配符的通用类型。
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
}
}
通配符没有单独的存在。它们总是用作泛型的类型参数 类 例如: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));
}
}