使用 'super' 关键字限定泛型 [英] Bounding generics with 'super' keyword
问题描述
为什么我只能将 super
与通配符一起使用,而不能与类型参数一起使用?
Why can I use super
only with wildcards and not with type parameters?
比如在Collection
接口中,为什么toArray
方法不是这样写的
For example, in the Collection
interface, why is the toArray
method not written like this
interface Collection<T>{
<S super T> S[] toArray(S[] a);
}
推荐答案
super
绑定一个命名类型参数(例如
),而不是通配符(例如 <? super T>
)是 非法 仅仅是因为即使它被允许,它也不会做你希望它会做的事情,因为自从Object
是所有引用类型的终极super
,一切都是Object
,实际上没有界限.
super
to bound a named type parameter (e.g. <S super T>
) as opposed to a wildcard (e.g. <? super T>
) is ILLEGAL simply because even if it's allowed, it wouldn't do what you'd hoped it would do, because since Object
is the ultimate super
of all reference types, and everything is an Object
, in effect there is no bound.
在您的具体示例中,由于 any 引用类型数组是 Object[]
(通过 Java 数组协方差),因此它可以用作 <代码>S[] toArray(S[] a) (如果这种绑定是合法的)在编译时,它不会在运行时阻止 ArrayStoreException
.
In your specific example, since any array of reference type is an Object[]
(by Java array covariance), it can therefore be used as an argument to <S super T> S[] toArray(S[] a)
(if such bound is legal) at compile-time, and it wouldn't prevent ArrayStoreException
at run-time.
你试图提出的是给定的:
What you're trying to propose is that given:
List<Integer> integerList;
并给定这个 假设 super
绑定在 toArray
上:
and given this hypothetical super
bound on toArray
:
<S super T> S[] toArray(S[] a) // hypothetical! currently illegal in Java
编译器应该只允许编译以下内容:
the compiler should only allow the following to compile:
integerList.toArray(new Integer[0]) // works fine!
integerList.toArray(new Number[0]) // works fine!
integerList.toArray(new Object[0]) // works fine!
并且没有其他数组类型参数(因为 Integer
只有这 3 种类型作为 super
).也就是说,您试图阻止编译:
and no other array type arguments (since Integer
only has those 3 types as super
). That is, you're trying to prevent this from compiling:
integerList.toArray(new String[0]) // trying to prevent this from compiling
因为,根据您的论点,String
不是 Integer
的 super
.然而,Object
是Integer
的super
,String[]
是一个Object[]
,所以编译器仍然会让上面的代码编译,即使假设你可以做
!
because, by your argument, String
is not a super
of Integer
. However, Object
is a super
of Integer
, and a String[]
is an Object[]
, so the compiler still would let the above compile, even if hypothetically you can do <S super T>
!
所以下面的仍然可以编译(就像他们现在的方式一样),并且任何编译时检查都无法阻止运行时的ArrayStoreException
使用泛型类型边界:
So the following would still compile (just as the way they are right now), and ArrayStoreException
at run-time could not be prevented by any compile-time checking using generic type bounds:
integerList.toArray(new String[0]) // compiles fine!
// throws ArrayStoreException at run-time
泛型和数组不混用,这是它显示的众多地方之一.
Generics and arrays don't mix, and this is one of the many places where it shows.
再说一次,假设您有这个泛型方法声明:
Again, let's say that you have this generic method declaration:
<T super Integer> void add(T number) // hypothetical! currently illegal in Java
你有这些变量声明:
Integer anInteger
Number aNumber
Object anObject
String aString
您对
(如果合法)的意图是它应该允许 add(anInteger)
和 add(aNumber)
,当然还有 add(anObject)
,但不是 add(aString)
.好吧,String
是一个 Object
,所以 add(aString)
仍然会编译.
Your intention with <T super Integer>
(if it's legal) is that it should allow add(anInteger)
, and add(aNumber)
, and of course add(anObject)
, but NOT add(aString)
. Well, String
is an Object
, so add(aString)
would still compile anyway.
- Java 教程/泛型
关于泛型类型规则:
- 任何简单的方法解释为什么我不能做
List
?动物 = 新的 ArrayList () - java泛型(非)协方差
- 什么是原始类型和为什么我们不应该使用它?
- 解释原始类型
List
与List
的不同之处,后者又不同于List>
- Any simple way to explain why I cannot do
List<Animal> animals = new ArrayList<Dog>()
? - java generics (not) covariance
- What is a raw type and why shouldn’t we use it?
- Explains how raw type
List
is different fromList<Object>
which is different from aList<?>
关于使用
super
和extends
:Java 泛型:什么是 PECS?
- 来自Effective Java 2nd Edition:producer
extends
consumersuper
"
Java Generics: What is PECS?
- From Effective Java 2nd Edition: "producer
extends
consumersuper
"
这篇关于使用 'super' 关键字限定泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- From Effective Java 2nd Edition: "producer
- 来自Effective Java 2nd Edition:producer
- Explains how raw type
- 解释原始类型
- 任何简单的方法解释为什么我不能做