假设有一个Row
具有多个类型参数的框架类型,以及一个处理该Row
类型实例并使用所有这些类型参数的方法。
我有一种方法可以同时处理任何类型Row
,甚至是不同的类型,所以显然我使用的是通配符类型Row<?,?>
。问题是,如何调用采用 aRow<R,K>
和 a的方法Row<?,?>
?
我的思路:我不完全知道什么是类型Row<?,?>
,但肯定是某种Row
好的。而当一个泛型方法采用Row<R,K>
时,它意味着它想要做一些事情,R
但K
除此之外它可以处理任何类型的Row
. 所以我的“任何”类型应该与采用“任何”类型的方法一起使用,对吧?
我在下面附上了我尝试过的示例代码。最奇怪的是最后一行确实有效,但它并不比我认为的其他任何东西都更安全。所以基本上我想要一个比这更干净的解决方案,或者解释为什么这是要走的路。
package foo;
public class Experiment {
// Defined by a framework.
interface Key<K extends Key<K>> {}
interface Row<R extends Row<R, K>, K extends Key<K>> {}
static <R extends Row<R, K>, K extends Key<K>> R copyRow(R row) {
return row;
}
// My experiments below.
static class Wrapper<R extends Row<R, K>, K extends Key<K>> {
public final R row = null; // fixme
public final Class<R> clazz = null; // fixme
}
static <R extends Row<R, K>, K extends Key<K>> R upcast(Row<?, ?> row) {
return (R) row;
}
static <R extends Row<R, K>, K extends Key<K>> R upcast(Row<?, ?> row, Class<R> clazz) {
assert row.getClass().equals(clazz);
return (R) row;
}
public static void main(String[] args) {
Wrapper<?, ?> wr = null; // fixme
copyRow(wr.row); // Compilation error
copyRow(upcast(wr.row)); // Compilation error
copyRow(upcast(wr.row, wr.clazz)); // This works, why?
}
}
(您可以将此示例直接发送到 javac 以查看会发生什么。使用 Java 1.8:https ://pastebin.com/LB10ySsD )