以下是我的代码
class A<B2 extends B, A2 extends A<B2, A2>> {
C<B2, A2> c;
void test() {
c.acceptParameterOfTypeA(this);
}
}
class B {
}
class C<B2 extends B, A2 extends A<B2, A2>> {
void acceptParameterOfTypeA(A2 a) {
}
}
错误发生在c.acceptParameterOfTypeA(this);
。
错误是
类型C中的方法acceptParameterOfTypeA(A2)不是 适用于论点(A)
根据我的看法,方法acceptParameterOfTypeA
需要一个类型为A的参数,而在给出错误的行中的this
是A类型。
我做错了什么?如何解决这个问题?
如果它很重要,我使用Java8
答案 0 :(得分:8)
我将再次重命名您的类,以便一切都更具可读性。所以,让我们:
public class First<T extends Second, U extends First<T, U>> {
Third<T, U> c;
void test() {
c.acceptParameterOfTypeA(this);
}
}
class Second {
}
public class Third<X extends Second, Y extends First<X, Y>> {
void acceptParameterOfTypeA(Y a) {
}
}
根据c
成员(Third<T, U>
)的定义,我们可以得出结论c
将公开带有此签名的方法:
void acceptParameterOfTypeA(U a) { .. }
什么是U
? U
是First<T, U>
的子类型。
但是,如果U
在类型删除后可以用First
替换,那么这将意味着First extends First<T, First>
,这不是真的,因为U
代表子类型First
的{{1}},其参数化为Second
和First
的一些具体子类型。
要访问U
,您可以应用所谓的 Get This
方法。
首先,由于您需要U
,这是First
的子类型,但无法从First
获取,您可以引入abstract
返回它的方法:
abstract class First<T extends Second, U extends First<T, U>> {
Third<T, U> c;
void test() {
c.acceptParameterOfTypeA(getU());
}
abstract U getU();
}
然后,实现一个名为First
的{{1}}样本子类,其Fourth
扩展First
和T
的一些具体类型,例如:
U
在class Fourth extends First<Second, Fourth> {
Fourth getU() {
return this;
}
}
方法中,只需执行getU()
,因为这将在超类中返回return this;
的正确替代。
更多信息:
答案 1 :(得分:1)
简而言之,c.acceptParameterOfTypeA()
接受A2
。 this
的类型为A<B2, A2>
,但不知道是否A2
。仅知道A2
延伸A<B2, A2>
。
答案 2 :(得分:1)
根据kocko
的答案,原始问题有相同的解决方案:
public class Main {
abstract class A<A2 extends A<A2, B2>, B2 extends B<A2, B2>> {
B2 b;
void test() {
b.testMethod(getThis()); //getThis() instead of this;
}
abstract A2 getThis();
}
class B<A2 extends A<A2, B2>, B2 extends B<A2, B2>> {
void testMethod(A2 a) {
}
}
public void execute() {
}
public static void main(String[] args) {
Main main = new Main();
main.execute();
}
}
答案 3 :(得分:1)
我们可以通过删除不会导致问题的B
部分来简化它 -
class A<T extends A<T>>
{
void test(C<T> c)
{
c.acceptParameterOfTypeA(this); // ERROR
}
}
class C<T extends A<T>>
{
void acceptParameterOfTypeA(T a) {}
}
this
类型为A<T>
;问题是A<T> <: T
是否为假。
我们真正想要的是&#34;自我类型&#34;,以便this
类型为T
。我们在Java中没有这个。
通常我们将T extends A<T>
用于&#34;自我类型&#34 ;;但在某些用例中存在缺陷和不足。
正如kocko所提到的那样,T getThis()
就是一个补救办法。
你可以简单地做一个粗暴的演员(T)this
,这显然是T
的意图。
我首选的方法是简单地省略T
的范围,并将其重命名为This
以指示类型变量的用途。施放(This)this
看起来显然是正确的。查看我的其他post。这种方法通常有效;但它不起作用,因为C
需要This
来绑定A<This>
。更深层次的问题是A
和C
相互依赖,可能会重新设计。