Bri*_*idy 5 java generics parameterized
我有一个相当简单的问题.我找不到答案.
这两个代码片段有区别吗?有什么区别?
片段1:
public class BinaryTree<T extends Comparable<? super T>> {
...
public <E extends T> void add(E value) {
...
}
public <E extends T> void add(E value, Node node) {
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
Fragment2:
public class BinaryTree<T extends Comparable<? super T>> {
...
public void add(T value) {
...
}
public void add(T value, Node node) {
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
片段1指定明确的是,参数值必须是任一类型Ť或类型的子类型Ť.
Fragment2指定参数值必须是T类型.但是从我的小知识和经验来看,我认为我也可以在这里提供T的子类型.与fragment1相同.
我查看了这两个片段的反汇编字节码.确实存在差异:
< public <E extends T> void add(E);
---
> public void add(T);
Run Code Online (Sandbox Code Playgroud)
这只是反映了源代码......
我只是没有意义.而且我也找不到示例应用程序,它显示了差异.
感谢您的评论.
在这种情况下没有区别。让我们以 a 为例BinaryTree<Number>并尝试添加一个Integer:
BinaryTree<Number> numTree = new BinaryTree<>();
Integer i = 1;
numTree.add(i);
Run Code Online (Sandbox Code Playgroud)
对于片段 1,E可能会计算为Integer,但在这种情况下这是多余的。Integer 是 a Number,您也可以指定Numberfor E:
numTree.<Number>add(i);
Run Code Online (Sandbox Code Playgroud)
因此,第二个片段与第一个片段没有什么不同,并且不会因未声明不必要的类型参数而造成混乱。
在某些情况下,附加类型参数会很有用。想象一下,由于某种原因您想要返回传入的值:
public <E extends T> E add(E value) {
...
return value;
}
public <E extends T> E add(E value, Node node) {
...
return value;
}
Run Code Online (Sandbox Code Playgroud)
现在这对调用者很有用:
Integer i2 = numTree.add(i);
Run Code Online (Sandbox Code Playgroud)
对于第二个片段,这是不可能的,即使您传入了 ,也numTree.add只能返回 a 。NumberInteger
| 归档时间: |
|
| 查看次数: |
342 次 |
| 最近记录: |