【问题标题】:Forcing two parameters of a generic method to have the same concrete type强制泛型方法的两个参数具有相同的具体类型
【发布时间】:2014-11-10 02:38:02
【问题描述】:

我怎样才能有一个有两个参数的方法,两个参数都具有相同的具体类型?

例如,

boolean equals(Object a, Object b)

允许任何类型的a 和任何类型的b

我想强制使ab 具有相同的具体类型。我试过了

<T> boolean equals(T a, T b)

并向该方法输入DateString,预计会出现编译时错误,但我没有收到任何错误,因为T 将解析为? extends Serializable &amp; Comparable,因为DateString 都实现了SerializableComparable

【问题讨论】:

  • 你为什么要这样做?

标签: java generics methods


【解决方案1】:

正如其他用户所提到的,没有办法对特定方法强制执行此操作。但是,如果可能的话,您可以将此方法移至单独的参数化类,然后在方法签名中使用该参数。

例如:这是我想强制使用相同参数类型的方法。 (我试图获得 o1 和 o2 之间的差异)

public List&lt;Change&gt; getChanges(Object o1, Object o2);

我将此方法封装在一个参数化的类中。

public class DiffGenerator<T> { 
  public List<Change> getChanges(T o1, T o2) { 
  //code
 }
}

这可以用作: List&lt;Change&gt; changes = new DiffGenerator&lt;MyClass&gt;().getChanges(myClassOld, myClassNew);

【讨论】:

    【解决方案2】:

    问题是你的方法的签名变成了

    <? extends Object> boolean equals(? extends Object a, ? extends Object b)
    

    这没有给你任何选择。即使你打电话

    equals(new Date(), "hello world");
    

    编译器甚至不需要费力地确定参数类型的最低共同祖先。

    编辑

    有趣的事实。我知道我上面写的是真的,但看起来还是有点奇怪。所以我测试了

    <T> boolean equals(T a, T b) {
        return true;
    }
    
    <T,E> boolean equals(T a, E b) {
        return true;
    }
    

    编译器对它大喊大叫。原因是编译器确实没有什么区别,只是将两个方法都重写为

    boolean equals(? extends Object a, ? extends Object b)
    

    类型擦除后变为

    boolean equals(Object a, Object b)
    

    这是完全相同的签名。实际上,如果我保留您的方法 equals(T,T) 并添加另一个带有签名 equals(Object, Object) 的方法,编译器会继续说我在其他地方声明了相同的方法。

    长话短说,由于类型擦除,您的方法equals(T,T)equals(Object, Object) 相同,因此您不能强制使用相同的参数类型,至少在编译时,除非您专门为每个方法实现equals

    【讨论】:

      【解决方案3】:

      你不能,基本上。没有办法做到这一点。即使您可以通过简单的调用来禁止不同类型的参数,也可以使用强制转换来绕过它:

      equals((Object) date, (Object) string)
      

      如果您对参数的 execution-time 类型感兴趣,则只能在执行时对其进行测试。编译器无法知道 Date 类型的参数是否具有对 精确 java.util.Date 或某个子类的引用的值。

      【讨论】:

      • 感谢您的快速回答。
      猜你喜欢
      • 2020-11-26
      • 1970-01-01
      • 1970-01-01
      • 2011-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-27
      相关资源
      最近更新 更多