在Java中是否有可能缩小泛型类子类中的泛型类型?
在Java中,是否可以缩小泛型类的子类中的泛型类型? 我的案子是这样的:
class C<T> {
protected T foo() {...}
protected void bar(Supplier<T> foobar) {...}
}
class A<T extends B> extends C<T> {
public void someMethod(){
B b = foo(); // Compiler does not complain
bar(() -> createB()); // Compiler complains with "Type mismatch: cannot convert from B to T"
}
}
也许我所做的完全是愚蠢的,但我不明白为什么编译器不抱怨foo(),而是抱怨bar()
任何关于如何做或为什么不做这件事的建议,我们都将不胜感激:)
亲切问候,, 托马斯
# 1 楼答案
这是一个差异问题。你有
A<T extends B>
一个C<T>
的子类型。我们也有现在,当你
foo()
返回T
。我们(从类声明中)知道T extends B
是正确的。向上投射到超类型总是安全的,所以每个T
都是一个B
。现在考虑createB
是一个返回B
的函数bar
正在等待Supplier<T>
。也就是说,bar
期待着某种能产生T
的东西。createB
会产生T
吗?嗯,它产生一个B
。我们能把一个B
升到一个T
吗?不,我们知道T extends B
,但要将B
向上投射到T
,我们需要知道相反的情况:那B extends T
bar
中的T
出现在参数位置(逆变),而foo
中的T
出现在返回位置(协变)。这就解释了施法能力的差异。我们写信了吗然后你可以做
bar
的例子,但不能做foo
的例子,因为我们有相反的关系见What is PECS,这与这个问题有关。这更多的是关于呼叫站点差异,但是关于差异的讨论仍然是相关的
# 2 楼答案
根据@luk2302 comment:createB本身必须是泛型的,这样就可以参数化它以返回
T extends b