我有:
public class A implements BListener {
public interface AListener {}
}
public class B implements AListener {
public interface BListener {}
}
因此,如果我理解正确,则会发生循环继承,因为:
编译器转到 A 并说“嘿,A实现BListener,让我们去找BListener!”
然后当它试图找到BListener时,它最终会进入 B ,它说:
“嘿,BListener,A需要在B里面!但是等待!B需要AListener!让我们去找AListener!”
然后它到达A,重复一遍。我做对了吗?
顺便说一下,这个编译错误发生在Android开发上。
答案 0 :(得分:6)
它可能有助于把它画出来。
>A
is part of / \ inherits
V
AListener BListener
^
inherits \ / is part of
B<
一个可爱的圈子。如果没有已存在的其他人,则无法创建其中一个。
编译器是否是咖啡追逐它自己的尾巴的ADHD高的松鼠?
不,因为松鼠不会停止(直到咖啡因用完为止)。编译器会查找它,然后放弃。
注意:Eclipse有一个允许此设置的错误。
答案 1 :(得分:2)
经过进一步调查,我最初错了。
您注意到的行为的技术说明如下:
的Java语言规范章节如果
C
中提及T
,则T
类直接取决于类型extends
implements
的{{1}}或C
条款要么作为超类,要么作为超类 超级接口,或作为完全限定形式的限定符 超类或超接口名称。如果以下任何一项,则课程
C
取决于引用类型T
真:
C
直接取决于T
。C
直接依赖于I
上依赖({9.1})的接口T
。C
直接依赖于依赖D
的类T
(递归使用此定义)。如果某个类依赖于自身,那么这是一个编译时错误。
假设类在包com.example
中声明,让我们使用您的代码,使用类型用途的完全限定名称:
public class A implements com.example.B.BListener {
public interface AListener {}
}
public class B implements com.example.A.AListener {
public interface BListener {}
}
遵循上述JLS的规则
A
直接取决于BListener
,因为它在implements
条款中有提及。A
直接依赖于B
,因为它在超级接口的完全限定名称中被提及为限定符(BListener
为com.example.B.BListener
)B
直接取决于AListener
,因为它在implements
条款中有提及。B
直接依赖于A
,因为它在超级接口的完全限定名称中被提及为限定符(AListener
为com.example.A.AListener
)A
直接取决于取决于B
的{{1}}。因此A
取决于A
,并且应该发生编译错误。
在Eclipse中,如果您限定名称
,则会发生错误A
但是,如果您使用class A implements B.BListener {
public static interface AListener {
}
}
class B implements A.AListener {
public static interface BListener {
}
}
语句,则不会。我将与他们打开一个错误。