了解上界和下界 ?在 Java 泛型中 [英] Understanding upper and lower bounds on ? in Java Generics
问题描述
我真的很难理解通配符参数.我有几个问题.
?
作为类型参数只能在方法中使用.例如:printAll(MyList extends Serializable>)
我不能用?
作为类型参数定义类.我了解
的上限?
.printAll(MyList<? extends Serializable>)
意思是:printAll
将打印MyList
如果它有实现的对象Serialzable
接口."
我对super
有点问题.printAll(MyList super MyClass>)
意思是:printAll
将打印MyList
如果它有MyClass<的对象/code> 或任何扩展
"MyClass
的类(MyClass
的后代).
纠正我哪里出错了.
简而言之,只有T
or E
or K
or V
or N
可以用作定义泛型类的类型参数.?
只能在方法中使用
<小时>更新 1:
public void printAll(MyList super MyClass>){//代码代码代码}
根据 Ivor Horton 的书,MyList
意味着我可以打印 MyList
如果它有 MyClass
的对象或者它实现的任何接口或类.也就是说,MyClass
是一个下限.它是继承层次结构中的最后一个类.这意味着我最初的假设是错误的.
所以,假设 MyClass
看起来像:
public class MyClass extends Thread 实现 ActionListener{//任何}
那么,printAll()
将打印 if
1.列表中有MyClass
的对象
2、List
中有Thread
或ActionListener
的对象<小时>更新 2:
所以,在阅读了问题的许多答案后,这是我的理解:
<代码>?extends T 表示任何扩展
T
的类.因此,我们指的是T
的 孩子.因此,T
是上限.继承层次结构中最上层的类<代码>?super T 意味着任何类/接口,它是
T
的super
.因此,我们指的是T
的所有 父项.T
因此是下限.继承层次结构中最底层的类
?
作为类型参数只能在方法中使用.例如:printAll(MyList extends Serializable>)
我不能用?
作为类型参数定义类.
通配符 (?
) 不是正式的类型参数,而是可以用作类型参数.在你给出的例子中,?extends Serializable
作为类型参数提供给 printAll
方法的参数的泛型类型 MyList
.
方法也可以像类一样声明类型参数,例如:
static void printAll(MyList myList)
<块引用>
我了解 的上限?
.printAll(MyList extends Serializable>)
表示 printAll 将打印 MyList,如果它有实现 Serialzable 接口的对象
更准确地说,这意味着对printAll
的调用只有在传递一个MyList
时才会编译,该MyList
具有某种是或实现Serializable的泛型类型
.在这种情况下,它将接受 MyList
、MyList
等.
我对 super
有点问题.printAll(MyList super MyClass>)
表示 printAll 将打印 MyList 如果它有 MyClass 的对象或任何扩展 MyClass 的类(MyClass 的后代)
以super
为界的通配符是一个下界.所以我们可以说对printAll
的调用只有在传递一个MyList
的MyClass
或一些泛型类型时才会编译MyClass
的超类型.所以在这种情况下,它会接受 MyList
,例如MyList
,或 MyList
.
所以,假设 MyClass 看起来像:
public class MyClass extends Thread 实现 ActionListener{//任何}
那么,printAll() 将打印如果
- 列表中有 MyClass 的对象
- 列表中有Thread或ActionListener的对象
你走在正确的轨道上.但我想说例如如果列表中有 MyClass
的对象,它将打印"是有问题的.这听起来像是在定义运行时行为 - 泛型都是关于编译时检查的.例如,不能将 MyList
作为 MyList
,即使它可能通过继承包含 MyClass
的实例.我会改写为:
对 printAll(MyList super MyClass>)
的调用只有在传递 a 时才会编译:
MyList
MyList
MyList
MyList
MyList
MyList
MyList
其中X
是MyClass
、Thread
、Runnable
、ActionListener
、EventListener
或Object
.
<块引用>
所以,在阅读了问题的许多答案之后,这是我的理解:
<代码>?extends T 意味着任何扩展 T 的类.因此,我们指的是T 的孩子.因此,T 是上限.最上层在继承层次结构中
<代码>?super T 表示 T 的 super
的任何类/接口.因此我们是指的是 T 的所有父母. T 因此是下限.这继承层次结构中最底层的类
关闭,但我不会说T
的孩子"或T
的父母",因为这些界限是包括 -说T
或其子类型"和T
或其超类型"会更准确.
I am really having a tough time understanding the wild card parameter. I have a few questions regarding that.
?
as a type parameter can only be used in methods. eg:printAll(MyList<? extends Serializable>)
I cannot define classes with?
as type parameter.I understand the upper bound on
?
.printAll(MyList<? extends Serializable>)
means: "printAll
will printMyList
if it has objects that implement theSerialzable
interface."
I have a bit of an issue with thesuper
.printAll(MyList<? super MyClass>)
means: "printAll
will printMyList
if it has objects ofMyClass
or any class which extendsMyClass
(the descendants ofMyClass
)."
Correct me where I went wrong.
In short, only T
or E
or K
or V
or N
can be used as type parameters for defining generic classes. ?
can only be used in methods
Update 1:
public void printAll(MyList<? super MyClass>){
// code code code
}
Accordint to Ivor Horton's book, MyList<? super MyClass>
means that I can print MyList
if it has objects of MyClass
or any of the interfaces or classes it implements. That is, MyClass
is a lower bound. It is the last class in the inheritance hierarchy. This means my initial assumption was wrong.
So, say if MyClass
looks like:
public class MyClass extends Thread implements ActionListener{
// whatever
}
then, printAll()
will print if
1. There are objects of MyClass
in the list
2. There are objects of Thread
or ActionListener
in the List
Update 2:
So, after having read the many answers to the question, here is my understanding:
? extends T
means any class which extendsT
. Thus, we are referring to the children ofT
. Hence,T
is the upper bound. The upper-most class in the inheritance hierarchy? super T
means any class / interface which issuper
ofT
. Thus we are referring to all the parents ofT
.T
is thus the lower bound. The lower-most class in the inheritance hierarchy
?
as a type parameter can only be used in methods. eg:printAll(MyList<? extends Serializable>)
I cannot define classes with?
as type parameter.
A wildcard (?
) isn't a formal type parameter, but rather can be used as a type argument. In the example you give, ? extends Serializable
is given as a type argument to the generic type MyList
, of the printAll
method's parameter.
Methods can also declare type parameters like classes, for example:
static <T extends Serializable> void printAll(MyList<T> myList)
I understand the upper bound on
?
.printAll(MyList<? extends Serializable>)
means printAll will print MyList if it has objects that implement the Serialzable interface
More accurately, it means a call to printAll
will compile only if it is passed a MyList
with some generic type that is or implements Serializable
. In this case it would accept a MyList<Serializable>
, MyList<Integer>
, etc.
I have a bit of an issue with the
super
.printAll(MyList<? super MyClass>)
means printAll will print MyList if it has objects of MyClass or any class which extends MyClass (the descendants of MyClass)
A wildcard bounded with super
is a lower bound. So we could say a call to printAll
will compile only if it is passed a MyList
with some generic type that is MyClass
or some super-type of MyClass
. So in this case it would accept MyList<MyClass>
, e.g. MyList<MyParentClass>
, or MyList<Object>
.
So, say if MyClass looks like:
public class MyClass extends Thread implements ActionListener{ // whatever }
then, printAll() will print if
- There are objects of MyClass in the list
- There are objects of Thread or ActionListener in the list
You're on the right track. But I think saying e.g. "it will print if there are objects of MyClass
in the list" is problematic. That makes it sound like you're defining runtime behavior - generics are all about compile time checks. For example wouldn't be able to pass a MyList<MySubclass>
as an argument for MyList<? super MyClass>
, even though it might contain instances of MyClass
, by inheritance. I would reword it to:
A call to printAll(MyList<? super MyClass>)
will compile only if it is passed a:
MyList<MyClass>
MyList<Thread>
MyList<Runnable>
MyList<ActionListener>
MyList<EventListener>
MyList<Object>
MyList<? super X>
whereX
isMyClass
,Thread
,Runnable
,ActionListener
,EventListener
, orObject
.
So, after having read the many answers to the question, here is my understanding:
? extends T
means any class which extends T. Thus, we are referring to the children of T. Hence, T is the upper bound. The upper-most class in the inheritance hierarchy
? super T
means any class / interface which issuper
of T. Thus we are referring to all the parents of T. T is thus the lower bound. The lower-most class in the inheritance hierarchy
Close, but I wouldn't say "children of T
" or "parents of T
", since these bounds are inclusive - it would be more accurate to say "T
or its subtypes", and "T
or its supertypes".
这篇关于了解上界和下界 ?在 Java 泛型中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!