Parameterized methods in generic class type

依然范特西╮ 提交于 2019-12-06 03:45:54

问题


I have a rather simple question. I can't find an answer by searching though.

Is there a difference in these two code-fragments? And what is the difference?

Fragment1:

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) {
      ...
   }
   ...
}

Fragment2:

public class BinaryTree<T extends Comparable<? super T>> {
   ...
   public void add(T value) {
      ...
   }

   public void add(T value, Node node) {
      ...
   }
   ...
}

Fragment1 specifies explicitly, that the parameter value must be either of type T or a subtype of type T.

Fragment2 specifies, that the parameter value must be of type T. But from my little knowledge and experience I think that I can also supply a subtype of T here. So same as fragment1.

I looked at the disassembled byte codes of these two fragments. Indeed there is a difference:

<   public <E extends T> void add(E);
---
>   public void add(T);

That just reflects the source code ...

I just don't get the meaning. And I also can't find an example application, which shows the difference.

Thanks for comments.


回答1:


In this case there is no difference. Let's take for example a BinaryTree<Number> and try adding an Integer:

BinaryTree<Number> numTree = new BinaryTree<>();
Integer i = 1;
numTree.add(i);

With fragment 1, E may evaluate to Integer, but that's superfluous in this case. Integer is a Number, and you could just as well specify Number for E:

numTree.<Number>add(i);

For this reason the second snippet is no different than the first, and less confusing for not declaring an unnecessary type parameter.


There are situations where an additional type parameter would be useful. Imagine for some reason you wanted to return the passed in value:

public <E extends T> E add(E value) {
   ...
   return value;
}

public <E extends T> E add(E value, Node node) {
   ...
   return value;
}

This would now be useful to the caller:

Integer i2 = numTree.add(i);

With the second snippet that wouldn't be possible, and numTree.add could only return a Number even if you passed in an Integer.




回答2:


No, there is no difference between the two variations of the add() method. Java's method arguments already establish an upper bound on the accepted type, which is the same constraint accomplished by using the extends form of your type variable <E extends T>.

Your type variable adds no new information nor does it add any additional constraints. It was already legal to pass an argument of type T or any type that extends T. Your type variable <E extends T> does provide a way to refer to the actual argument type again—say, if there was a second method parameter that you wanted to ensure was of the same type as the first—but in your case, you're not making use of E.



来源:https://stackoverflow.com/questions/12130940/parameterized-methods-in-generic-class-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!