我认为你不能将Java泛型类型参数绑定到下限(即使用super关键字).我正在阅读Angelika Langer Generics常见问题解答中有关该主题的内容.他们说这基本上归结为下限无用("没有任何意义").
我不相信.我可以想象它们的用途可以帮助您更灵活地生成类型化结果的库方法的调用者.想象一个方法,它创建一个用户指定大小的数组列表,并用空字符串填充它.一个简单的声明就是
public static ArrayList<String> createArrayListFullOfEmptyStrings(int i);
Run Code Online (Sandbox Code Playgroud)
但这对您的客户来说是不必要的限制.为什么他们不能像这样调用你的方法:
//should compile
List<Object> l1 = createArrayListFullOfEmptyStrings(5);
List<CharSequence> l2 = createArrayListFullOfEmptyStrings(5);
List<String> l3 = createArrayListFullOfEmptyStrings(5);
//shouldn't compile
List<Integer> l4 = createArrayListFullOfEmptyStrings(5);
Run Code Online (Sandbox Code Playgroud)
在这一点上,我很想尝试以下定义:
public static <T super String> List<T> createArrayListFullOfEmptyStrings(int size) {
List<T> list = new ArrayList<T>(size);
for(int i = 0; i < size; i++) {
list.add("");
}
return list;
}
Run Code Online (Sandbox Code Playgroud)
但它不会编译; super在这种情况下,关键字是非法的.
上面我的例子是一个坏例子(忽略我在下面说的)?为什么这里没有下限?如果它有用,那么Java中不允许它的真正原因是什么?
我知道一个更好的组织可能是这样的:
public static void populateListWithEmptyStrings(List<? super String> list, int size); …Run Code Online (Sandbox Code Playgroud) Java要求将有界类型参数实例化到其上界类以进行强制转换,例如:
<T extends Integer> void passVal (T t) {
Integer number = 5;
t = (T) number; // Without cast a compile error is issued
}
Run Code Online (Sandbox Code Playgroud)
T在声明时已经被限制Integer为其子类之一(我知道,没有子类),而且在我看来,任何有界类型参数都只能实例化为其上界类或其子类之一,因此为什么需要演员表?
另外,我知道如果不是通过此方法之外的调用实例化该参数,则不是这种情况,因此请不要提供它作为答案;该问题特定于在其声明的类/方法中实例化的有界类型参数。
在Java 8中,类java.util.Optional(javadoc)类提供"Maybe"Monad或Option Type的功能.
更直接:
public final class java.util.Optional <T> extends Object
容器对象,可能包含也可能不包含非null值.如果存在值,则isPresent()将返回true,get()将返回该值.
其中一种方法是:
<U>可选<U>地图(功能<?super T,?extends U> mapper)
如果存在值,则将提供的映射函数应用于该值,如果结果为非null,则返回描述结果的Optional.
问题是为什么map()在类型上使用类型通配符U.
我对类型通配符的理解很简单:
? super T从指定从该组由子类路径给定类型的一些Object到T(两者Object并T包括)联合在拉出任何subinterfacing路径上找到的组接口"作为sidedish"通过implements.
并? extends U简单地从扩展U(U包括)的类集合中指定一些类型.
所以可以写一下:
<U>可选<U>地图(功能<?super T,U> mapper)
没有丢失信息.
或不?
我知道我的问题可能看起来像重复的问题,但我已经阅读了许多类似的问题和答案,但我对下限 (? super) 特别感到困惑。请考虑这段代码。
import java.util.*;
public class Main {
// just adds numbers to the List nums
static void myadd(List<? super Number> nums){
nums.add(1);
nums.add(1.0f);
nums.add(1.1);
nums.add(3l);
}
public static void main(String[] args) {
List empty= new ArrayList<>();
myadd(empty);
System.out.println(empty);
}
}
Run Code Online (Sandbox Code Playgroud)
这是执行它的链接。
根据甲骨文文档
下限通配符将未知类型限制为特定类型或该类型的超类型
Number类是 Double、Float、Integer、Long 和 Short 类的超类,那么为什么这个方法执行得很好呢? 此方法 (myadd) 应该仅适用于 Number 类或其超类型的直接实例的对象,而不适用于其子类。
我已阅读以下答案,但我的疑问仍不清楚。
如果有人能解释我将不胜感激。