[英]Java Generics wildcard extends final class
Why does Java doesn't throw any warning when compiling my TestGenerics
class
, considering that the String
class
is final
and cannot be extended? 为什么Java在编译我的
TestGenerics
class
时不会抛出任何警告,因为String
class
是final
并且无法扩展?
import java.util.*;
public class TestGenerics {
public void addStrings(List<? extends String> list) {
// some code here
}
}
}
Let's say I had a method like this: 假设我有一个这样的方法:
public List<? extends T> filterOutNulls(List<T> input) { ...
Granted, not the best signature in the world, but still perfectly legal. 当然,这不是世界上最好的签名,但仍然完全合法。 What would happen if I passed a
List<String>
to that method? 如果我将
List<String>
传递给该方法会发生什么? According to the signature, it returns a List<? extends String>
根据签名,它返回一个
List<? extends String>
List<? extends String>
. List<? extends String>
。 If Java disallowed that type, it'd be impossible to use this method for List<String>
(or at least, it'd be impossible to use the return value). 如果Java不允许使用该类型,则不可能将此方法用于
List<String>
(或者至少,不可能使用返回值)。
Secondarily, the extends
syntax is still useful in this case, since List<String>
and List<? extends String>
其次,在这种情况下,
extends
语法仍然有用,因为List<String>
和List<? extends String>
List<? extends String>
have different restrictions -- specifically, you can't add anything but a null
literal to List<? extends String>
List<? extends String>
有不同的限制 - 具体来说,你不能向List<? extends String>
添加除null
文字之外的任何内容List<? extends String>
List<? extends String>
. List<? extends String>
。 I'll sometimes use ? extends
我有时会用
? extends
? extends
to signify that a collection is read-only (since the only T
s you can pass in are null
), and ? super
? extends
表示集合是只读的(因为你可以传入的唯一T
是null
),并且? super
? super
to signify write-only (since you can only get out T
s as Object
). ? super
表示只写(因为你只能将T
s作为Object
)。 This isn't completely fool-proof (you can still call remove methods, pass in null
s, downcast, etc) but serves as a gentle reminder of how the collection is probably meant to be used. 这不是完全万无一失的(你仍然可以调用remove方法,传入
null
s,downcast等),但它可以温和地提醒你如何使用这个集合。
The compiler doesn't really take note of that fact, because it doesn't matter. 编译器并没有真正注意到这一事实,因为它并不重要。
String
s are still allowed in the list, and in the final product, the possibility of anything extending String
is not found. String
仍然允许在列表中,并且在最终产品中,找不到任何扩展String
的可能性。 After erasure , it comes out like this: 擦除后 ,它出现如下:
public void addStrings(List list)
As you can see, there is now no suggestions of a class extending String
. 如您所见,现在没有关于扩展
String
的类的建议。 If you do create a class extending String
, that will be itself a compile error. 如果你确实创建了一个扩展
String
的类,那么它本身就是一个编译错误。 There's no need for javac to worry about that. javac不需要担心这一点。
The type system does not consider List<String>
and List<? extends String>
类型系统不考虑
List<String>
和List<? extends String>
List<? extends String>
equivalent, even though at the time of compiling, String
has no subtypes other than itself, therefore any object that is a List<? extends String>
List<? extends String>
equivalent,即使在编译时, String
没有自身以外的子类型,因此任何对象都是List<? extends String>
List<? extends String>
must also be a List<String>
. List<? extends String>
也必须是List<String>
。
One explanation is that final
is not final - it's ok to remove final
from a class and nothing should break: http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.2 一种解释是,
final
不是最终的 - 可以从类中删除final
并且没有任何内容可以破解: http : //docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls- 13.4.2
It's not without precedence that the type system takes final
into consideration; 并不是没有优先考虑类型系统
final
考虑; for example, we cannot cast a String
to a Runnable
, because the compiler figures that if an object is String
, it cannot be some unknown subclass that implements Runnable
. 例如,我们不能将一个
String
转换为Runnable
,因为编译器认为如果一个对象是String
,它不能是一个实现Runnable
未知子类。
If we want generics also to make reasoning like that and deduce that List<String>
and List<? extends String>
如果我们希望泛型也能像这样推理并推导出
List<String>
和List<? extends String>
List<? extends String>
are equivalent, it'll make typing rules even more complicated. List<? extends String>
是等价的,它会使输入规则更加复杂。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.