在学习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());
第一次调用没有错误,但第二次调用会导致编译时错误。看来只要t
和s
都是java.lang.Number
的子类型,就不会发生错误,无论s
是否是 t
的子类型。
我的问题:我们如何声明一个接收两个参数的方法,并且保证其中一个参数是另一个参数的子类型?
最佳答案
有两个问题:
就泛型而言,任何类型都是其自身的子类型。无法声明
S extends T
这样S
和T
不能是同一类型。此外,即使有可能,它在这里也不会有太大影响,因为S
的任何实例。也可以传递为T
.类型推断会尽力使方法编译。如果
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/