【发布时间】:2018-05-21 17:48:32
【问题描述】:
假设有一个带有多个类型参数的框架类型Row,以及一个适用于Row 类型实例并使用所有这些类型参数的方法。
我有一个方法可以处理任何类型的Row,甚至可以同时处理不同的类型,所以很明显我使用的是通配符类型Row<?,?>。问题是,如何调用带有Row<R,K> 和Row<?,?> 的方法?
我的思路:我不完全知道Row<?,?> 是什么类型,但肯定是某种Row 好吧。当一个泛型方法采用Row<R,K> 时,它意味着它想对R 和K 做一些事情,否则它可以处理任何类型的Row。所以我的“any”类型应该与采用“any”类型的方法一起工作,对吧?
我在下面附上了我尝试过的示例代码。最奇怪的是最后一行确实有效,但它并不比我认为的其他任何东西都更安全。所以基本上我想要一个比这更干净的解决方案,或者解释为什么这是要走的路。
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)
【问题讨论】:
-
您应该能够将
Row<?, ?>传递给采用Row<R, K>的泛型方法,其中R和K是泛型类型。我不确定是什么问题?你的行copyRow(wr.row)也适合我。 -
当 R 和 K “相关”时不会。这就是我在评论说“错误”的地方得到的:pastebin.com/LB10ySsD
-
我用的是openjdk的javac 1.8,你用什么编译这段代码?
-
我使用的是 eclipse 4.7.3a,但看起来
javac拒绝它直到版本 11。 -
是的,IntelliJ 也不给我红色下划线,只有当我尝试编译它时。当我将静态助手移动到 Wrapper 中时,最后一行也不再起作用。 upcast() hack 必须在外部,在静态上下文中,然后最后一行工作......
标签: java generics types wildcard f-bounded-polymorphism