Java 协变返回类型&;抛出声明
在下面的层次结构中 以下是针对此问题的编译代码:Java 协变返回类型&;抛出声明,java,javac,throws,covariant-return-types,Java,Javac,Throws,Covariant Return Types,在下面的层次结构中 以下是针对此问题的编译代码: class T3 {} class T2 extends T3{} class T1 extends T2{} class T5 extends T1{} class E3 extends Throwable {} class E2 extends E3 {} class E1 extends E2 {} class E5 extends E1 {} interface I1{ T1 m() throws E1; } interfa
class T3 {}
class T2 extends T3{}
class T1 extends T2{}
class T5 extends T1{}
class E3 extends Throwable {}
class E2 extends E3 {}
class E1 extends E2 {}
class E5 extends E1 {}
interface I1{
T1 m() throws E1;
}
interface I2{
T2 m() throws E2;
}
interface I3{
T3 m() throws E3;
}
interface I4 extends I1, I2, I3{
}
interface I5 extends I1, I2, I3{
T5 m() throws E5;
}
在上面的代码中,接口I4
和接口I5
被编译,因为
(一)
接口I4仅在以下情况下扩展I1、I2、I3
T1扩展T2
&T1扩展T3
&T2扩展T3
及
E1扩展E2
&E1扩展E3
&E2扩展E3
(二)
接口I5扩展了I1、I2、I3
并覆盖m()
作为T5 m()抛出E5代码>仅当
T5扩展T1
和T5扩展T2
和T5扩展T3
及
E5扩展E1
和E5扩展E2
和E5扩展E3
关于协变返回类型和声明方面
我可以说,代码编译成功是因为上述两条规则是有效和必要的吗?是的,您可以说代码编译正确是因为这些规则是有效和必要的
如果T5没有扩展T1、T2和T3,那么I4和I5将不会编译
如果E5没有扩展E1、E2和E3,那么I5将不会编译(I4将继续编译,因为理论上I4的实现者可以创建自己的扩展E1、E2和E3的异常类)。编译代码是因为Java允许:
- 这种技术称为协变返回类型,意味着允许返回类型在与子类相同的方向上变化
- 利斯科夫替代原则:
以下是您代码的UML图:
I4
接口有3个方法m()
,但它们的返回类型不同。
I5
接口有4个方法m()
,它们的返回类型也不同
以下是一些相关帖子:和。如果您不确定问题是什么,请查看查询edit@overexchange你应该澄清你的问题,而不是批评这个答案。