java - 如何定义一个方法,该方法接收两个类型为 T 的参数,以及在 java 中扩展 T 的 S ?

标签 java generics generic-method

在学习Java泛型时,我想知道是否可以声明一个接收两个参数的方法,第一个参数是泛型类型T,第二个参数是泛型类型S,它扩展(或相同)输入 as) T。所以我开始对此进行实验,并编写了以下方法声明:

public static <T, S extends T> void testMethod(T t, S s)
{
    System.out.println("We are inside testMethod.");
}

然后我通过以下两种方式调用这个方法:

java.lang.Integer num1 = new java.lang.Integer(0);
java.lang.Integer num2 = new java.lang.Integer(1);

testMethod(num1, num2);
testMethod(num1, new Object());

预计第二次调用会导致编译时异常。但程序编译并运行没有错误。接下来,我更改了方法 testMethod 声明,如下所示:

public <T extends java.lang.Number, S extends T> void testMethod(T t, S s)

通过以下调用:

testMethod(new Integer(0), new Double(1.1));
testMethod(new Integer(0), new Object());

第一次调用没有错误,但第二次调用会导致编译时错误。看来只要ts都是java.lang.Number的子类型,就不会发生错误,无论s 是否是 t 的子类型。

我的问题:我们如何声明一个接收两个参数的方法,并且保证其中一个参数是另一个参数的子类型?

最佳答案

有两个问题:

  1. 就泛型而言,任何类型都是其自身的子类型。无法声明S extends T这样ST不能是同一类型。此外,即使有可能,它在这里也不会有太大影响,因为 S 的任何实例。也可以传递为 T .

  2. 类型推断会尽力使方法编译。如果S与第一个参数的类型不兼容,编译器将推断最近的共同祖先为 T 。您可以通过显式指定 T 来避免此问题。当您调用该方法时:

    ThisClass.<Integer, Integer>testMethod(1, 2);    // compiles
    ThisClass.<Integer, Integer>testMethod(1, 2.0);  // does not compile
    

事实是,最终,该方法本身无法强制执行 S 的要求。是 t 的子类型(甚至兼容)的类型。我认为没有任何方法可以解决这个问题。

关于java - 如何定义一个方法,该方法接收两个类型为 T 的参数,以及在 java 中扩展 T 的 S ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50163156/

相关文章:

java - Spring:将值作为对象形式映射并传递给 Controller ​​以进行查看

java - 如何在 android studio 中使用弹出窗口按钮打开新 Activity ?

java - 初始化泛型类型的 Java 泛型数组

swift - 为什么我需要将属性强制转换为与该属性具有相同签名的泛型方法?

java - 方法返回类型前的 <T> 是什么意思?

java - Java 源文件是否可以在编译时运行任意代码?

java - list 文件不包含我项目中的正确 Activity

objective-c - 为什么通用 NSDictionary 不警告我键入错误的键插入/分配?

java - 泛型方法返回类型

java - 为什么在静态泛型方法的返回类型之前需要类型参数