Mar*_*ers 48 java generics bounds
我认为你不能将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);
List<CharSequence> list = new ArrayList<CharSequence>();
populateListWithEmptyStrings(list, 5);
Run Code Online (Sandbox Code Playgroud)
我们为了这个问题的目的可以假装由于一个要求,我们需要在一个方法调用中做两个操作吗?
@Tom G(理所当然地)问有什么好处List<CharSequence>
会超过a List<String>
.首先,没有人说返回的列表是不可变的,所以这里有一个优点:
List<CharSequence> l2 = createArrayListFullOfEmptyStrings(5);
l2.add(new StringBuilder("foo").append("bar"));
Run Code Online (Sandbox Code Playgroud)
Ber*_*t F 15
基本上,它不够用.
我认为你的例子指出了下限的唯一优势,FAQ调用的一个功能Restricted Instantiation
:
底线是:所有"超级" 界限会购买你的是限制,只有超类型的数字可以用作类型参数.....
但正如其他帖子指出的那样,甚至这个功能的用处也是有限的.
由于多态性和特化的性质,上界比下界更有用,如FAQ(访问非静态成员和类型擦除)所述.我怀疑下界引入的复杂性不值得其有限的价值.
OP:我想补充一下,我认为你确实表明它很有用,只是没用.想出无可辩驳的杀手级用例,我将支持JSR.:-)
irr*_*ble 11
例如,规范确实讨论了类型参数的下界
4.10.2
类型变量是其下限的直接超类型.
5.1.10
一个新的类型变量......其下限
似乎一个类型变量只有一个(非空)下界,如果它是通配符捕获的合成结果.如果语言允许所有类型参数的下限,该怎么办?可能它不会造成很多麻烦,并且它被排除在外只是为了保持泛型更简单(好......)更新据说,对有界类型参数的理论研究并未彻底进行.
更新:声称下限的论文没问题:丹尼尔史密斯的"Java类型推断是否破坏:我们可以修复它"
RETRACT:以下参数是错误的.OP的例子是合法的.
你的具体例子不是很有说服力.首先,它不是类型安全的.返回的列表确实是一个List<String>
,将它视为另一种类型是不安全的.假设您的代码编译:
List<CharSequence> l2 = createArrayListFullOfEmptyStrings(5);
Run Code Online (Sandbox Code Playgroud)
那么我们可以添加非String,这是错误的
CharSequence chars = new StringBuilder();
l2.add(chars);
Run Code Online (Sandbox Code Playgroud)
好吧a List<String>
不是,但有点像CharSequence列表.您的需求可以通过使用通配符来解决:
public static List<String> createArrayListFullOfEmptyStrings(int size)
// a list of some specific subtype of CharSequence
List<? extends CharSequence> l2 = createArrayListFullOfEmptyStrings(5);
// legal. can retrieve elements as CharSequence
CharSequence chars = l2.get(0);
// illegal, won't compile. cannot insert elements as CharSequence
l2.add(new StringBuilder());
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8205 次 |
最近记录: |