问题描述
我知道有一个类似的问题已经发布,尽管我认为我有点不同......
假设您有两种方法:
//有界的类型参数
private static< T extends Number> void processList(List< T> someList){
}
//上限通配符
private static void processList2(List< ;? extends Number> someList){
// ...
}
据我所知,方法接受类型为 Number 或 List 的参数 List > Number 的子类型。
但这两种方法毕竟有什么区别?
- 使用第一种语法,您可以将元素添加到 someList 中,但第二种则不能。这通常被称为,并且通常称为PUT和GET prinicple。
- 使用第一种语法,您可以获得类型参数 T 的句柄,因此您可以使用它来执行此类操作在 T 类型的方法中定义局部变量,对类型 T 进行引用,调用可用的方法在由 T 等表示的类中,但是对于第二种语法,您没有该类型的句柄,因此您无法执行任何操作。 第二种方法实际上可以调用第一种方法,即
捕获通配符。这是通过辅助方法
通配符的最常见方式。
private static< T extends Number> void processList(List< T> someList){
T n = someList.get(0);
someList.add(1,n); //允许添加。
}
private static void processList2(List< ;? extends Number> someList){
Number n = someList.get(0);
//someList.add(1,n);//编译错误。不允许添加。
processList(someList); // Helper方法捕获通配符
}
ul>
请注意,由于泛型是编译时糖,所以在更广泛的层面上的这些差异仅限于编译。
I know that there was a similar question already posted, although I think mine is somewhat different...
Suppose you have two methods:
// Bounded type parameter private static <T extends Number> void processList(List<T> someList) { } // Upper bound wildcard private static void processList2(List<? extends Number> someList) { // ... }
As far as I know, both methods accepts arguments, that are List of type Number or List of subtype of Number.
But what's the difference between the two methods after all?
There are several differences between the two syntaxes during compile time :
- With the first syntax, you can add elements to someList but with the second, you can't. This is commonly known as PECS and less commonly known as the PUT and GET prinicple.
- With the first syntax, you have a handle to the type parameter T so you can use it to do things such as define local variables within the method of type T, cast a reference to the type T, call methods that are available in the class represented by T, etc. But with the second syntax, you don't have a handle to the type so you can't do any of this.
The first method can actually be called from the second method tocapture the wildcard. This is the most common way to capture awildcard via a helper method.
private static <T extends Number> void processList(List<T> someList) { T n = someList.get(0); someList.add(1,n); //addition allowed. } private static void processList2(List<? extends Number> someList) { Number n = someList.get(0); //someList.add(1,n);//Compilation error. Addition not allowed. processList(someList);//Helper method for capturing the wildcard }
Note that since generics are compile time sugar, these differences at a broader level are only limited to the compilation.
这篇关于有界类型参数与上界通配符的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!