问题描述
为什么我只能在通配符中使用 super
,而不能使用类型参数?
例如,在为什么 toArray
方法不是这样写的?
界面集合< T> {
< S super T> S [] toArray(S [] a);
super
来绑定一个命名的类型参数(例如< S super T>
),而不是通配符(例如< ;?super T>
)是 ILLEGAL ,因为即使允许,它也不会做你希望它做的事情,因为 Object
是所有引用类型的最终 super
,并且所有内容都是 Object
, 实际上是没有界限的。
在具体的例子中,因为任何引用类型的数组都是一个 Object []
(通过Java数组协变),因此它可以用作< S super T>的参数。在编译时,S [] toArray(S [] a)
(如果这样的绑定是合法的),并且它不会阻止 ArrayStoreException
在
$ b
您试图建议的是: C $ C>列表与LT;整数> integerList;
并给出这个假设 super
绑定在 toArray
:
< S super T> ; S [] toArray(S [] a)//假设!目前在Java中是非法的
编译器应该只允许编译以下代码:
integerList.toArray(new Integer [0])//正常工作!
integerList.toArray(new Number [0])//正常工作!
integerList.toArray(new Object [0])//正常工作!
并且没有其他数组类型参数(因为 Integer
只有 super
)这三种类型。也就是说,你试图阻止编译:
integerList.toArray(new String [0])//尝试以防止编译
,因为您的论点 String
不是超级
的整数
。 , Object
是 super
的整数
,并且一个 String []
是一个 Object []
,所以编译器仍然即使假设你可以做< S super T>
!
所以下面的仍然会被编译(就像它们现在的样子),并且在运行时 c $ c> ArrayStoreException
不能被任何编译阻止使用泛型类型边界检查时间:
integerList.toArray(new String [0])//编译得很好!
//在运行时抛出ArrayStoreException
泛型和数组不混合,这是它显示的许多地方之一。
非数组示例
再说一遍,假设您有这个泛型方法声明:
< T super Integer> void add(T number)//假设!目前在Java中是非法的
你有这些变量声明:
整数anInteger
数字a数字
对象anObject
字符串aString
您打算使用< T super Integer>
(如果它是合法的),它应该允许 add(anInteger)
和 add(aNumber)
,当然 add(anObject)
,但不是 add(aString)
。那么, String
是一个 Object
,所以 add(aString)
仍然可以编译。
另请参阅
问题
关于泛型键入规则: 在使用 Why can I use For example, in the In your specific example, since any array of reference type is an What you're trying to propose is that given: and given this hypothetical the compiler should only allow the following to compile: and no other array type arguments (since because, by your argument, So the following would still compile (just as the way they are right now), and 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: And you have these variable declarations: Your intention with On generics typing rules: On using 这篇关于使用“超级”关键字绑定泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
List
与 List< Object>
的不同之处,它与<$ c
$ b $ p
$ b 超级
和扩展
:
extends
consumer super
super
only with wildcards and not with type parameters?Collection
interface, why is the toArray
method not written like thisinterface Collection<T>{
<S super T> S[] toArray(S[] a);
}
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.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.List<Integer> integerList;
super
bound on toArray
:<S super T> S[] toArray(S[] a) // hypothetical! currently illegal in Java
integerList.toArray(new Integer[0]) // works fine!
integerList.toArray(new Number[0]) // works fine!
integerList.toArray(new Object[0]) // works fine!
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
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
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
A non-array example
<T super Integer> void add(T number) // hypothetical! currently illegal in Java
Integer anInteger
Number aNumber
Object anObject
String aString
<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.See also
Related questions
List<Animal> animals = new ArrayList<Dog>()
?List
is different from List<Object>
which is different from a List<?>
super
and extends
:Java Generics: What is PECS?
extends
consumer super
"super
and extends
in Java Generics<E extends Number>
and <Number>
?List<? extends Number>
data structures? (YOU CAN'T!)