简体   繁体   English

通用类类型的参数化方法

[英]Parameterized methods in generic class type

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

Fragment2: 片段2:

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 . 片段1指定明确的是,参数必须是类型TT类型的亚型。

Fragment2 specifies, that the parameter value must be of type T . Fragment2指定参数必须为T类型。 But from my little knowledge and experience I think that I can also supply a subtype of T here. 但是根据我的一点知识和经验,我认为我也可以在这里提供T的子类型。 So same as fragment1. 与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. 感谢您的评论。

In this case there is no difference. 在这种情况下没有区别。 Let's take for example a BinaryTree<Number> and try adding an Integer : 让我们以BinaryTree<Number>为例,尝试添加一个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. 对于片段1, E可以求值为Integer ,但这在这种情况下是多余的。 Integer is a Number , and you could just as well specify Number for E : Integer 是一个 Number ,您也可以为E指定Number

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 . 使用第二个代码段是不可能的,即使您传入IntegernumTree.add也只能返回一个Number

No, there is no difference between the two variations of the add() method. 不, add()方法的两个变体之间没有区别。 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> . Java的方法参数已经在接受的类型建立了一个上限 ,这是通过使用类型变量<E extends T>extends形式实现的相同约束。

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 . 传递类型T 或任何扩展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 . 类型变量<E extends T>确实提供了一种再次引用实际参数类型的方法-例如,如果要确保第二个方法参数与第一个参数具有相同的类型,但是在您的情况下,您可以不使用E

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM