[英]Why can't I use the wildcard (?) as type of parameter, field, local variable, or as return type of a method?
The Oracle doc about Wildcards in generics says, 关于泛型中的通配符的Oracle 文档说,
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).
有时作为返回类型 (虽然更好的编程实践更具体)。
I have tried all four in the following class, and got compiler errors on each one. 我在下面的类中尝试了所有四个,并且在每个类中都有编译器错误。 Why?
为什么? What am I doing wrong?
我究竟做错了什么?
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
}
The ?
的
?
character is the wildcard type argument . character是通配符类型参数 。
The article begins with 文章开头
In generic code , the question mark (?), called the wildcard, represents an unknown type.
在通用代码中 ,称为通配符的问号(?)表示未知类型。
The only place you can use that syntax is as part of generic code, ie. 您可以使用该语法的唯一地方是通用代码的一部分,即。 a generic type argument.
泛型类型参数。 The next sentence refers to generic code using the wildcard.
下一句是指使用通配符的通用代码。 So, for example
所以,例如
as the type of a parameter
作为参数的类型
you could have 你可以有
public static void shuffle(List<?> list) {
Or for 或者
as a local variable
作为局部变量
public void method() {
List<?> list = Arrays.asList(1, 2, 3);
Collections.shuffle(list);
System.out.println(list);
}
But 但
The wildcard is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype.
通配符从不用作泛型方法调用,泛型类实例创建或超类型的类型参数。
You can't use it as 你不能用它
Arrays.<?>asList(1, "", '5');
List<?> list = new ArrayList<?>();
...
public class MyList implements List<?> {/* whatever */}
The tutorial is terribly phrased. 该教程非常明确。 You cannot use a wildcard for any of the things listed.
您不能对列出的任何内容使用通配符。 You can use a generic type with a wildcard in it for those things.
您可以在其中使用带有通配符的泛型类型。
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
}
}
Wildcard can be used with <> operator in a generics concept introduced in java 5, used to represent unknown type . 在java 5中引入的泛型概念中,通配符可与<>运算符一起使用, 用于表示未知类型 。 Generics is used to define a class with member in generalized format.If you want to provide facility that while creating the object, user will specify the type of member then you can use the concept of generics.
泛型用于定义具有通用格式成员的类。如果要在创建对象时提供工具,用户将指定成员的类型,然后您可以使用泛型的概念。 It can be used only for the instance member can't be used with static member cause memory for static will be allocated only once.
它只能用于实例成员不能与静态成员一起使用,因为静态内存只会被分配一次。
Wildcard concept introduced in generics to restrict unknow type, let's say I have list which has wildcard and this wildcard extend Number wrapper class. 在泛型中引入的通配符概念用于限制未知类型,假设我有一个带有通配符的列表,这个通配符扩展了数字包装类。 That means list can work with Integer, Long, Short, Byte cause they extend Number wrapper class but not with String as String class do not extends Number wrapper class.
这意味着列表可以使用Integer,Long,Short,Byte,因为它们扩展了Number包装类,但没有使用String作为String类,不扩展Number包装类。
List<? extends Number> lt = new ArrayList<>();
Coming to you program, you have used wrong syntax, as i have mentioned wildcard can be used with <> operator. 来到你的程序,你使用了错误的语法,因为我已经提到过通配符可以与<>运算符一起使用。
We can't use wildcard while instantiating class like mentioned bellow -
我们不能在实例化上面提到的类时使用通配符 -
List<?> lt = new ArrayList<?>();
but we can use generics to provide the field as unknown type like I,N,S in employee class. 但我们可以使用泛型来提供字段作为员工类中的I,N,S等未知类型。 It's type we will provide while creating the object of the 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);
}
Here is the example of wildcard as return type of method - 以下是通配符作为返回类型方法的示例 -
List<?> method(List<?> data)
{
return data;
}
Wildcards does not have individual existence. 通配符没有个人存在。 They are always used as type parameter of Generic classes Ex :
List<? extends Number>
它们总是用作Generic类Ex:
List<? extends Number>
类型参数List<? extends Number>
List<? extends Number>
.I give one example covering all scenarios. 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.