类使用相同的方法实现两个接口,但不同的检查异常

Leo*_*Leo 4 java exception-handling

在SG Ganesh和Tushar Sharma撰写的"Oracle认证专业Java SE 7程序员考试1Z0-804和1Z0-805综合OCPJP 7认证指南"一书中,

"如果在2个或更多接口中声明了一个方法,并且该方法声明在throws子句中抛出不同的异常,则实现应列出所有这些异常"(第347页)

那么,我试过这个

public interface I1 {
    public void x() throws I1Exception;
}

public interface I2 {
    public void x() throws I2Exception;
}

public class I1Exception extends Exception {
}

public class I2Exception extends Exception {
}

public class Sample implements I1, I2{

    @Override
    public void x() throws I2Exception {
        throw new I2Exception();        
    }

    @Override
    public void x() throws I1Exception {
        throw new I1Exception();        
    }

}
Run Code Online (Sandbox Code Playgroud)

当然,异常不是方法签名的一部分,因此编译器抱怨第二种方法是重复的.

另一方面

@Override
public void x() throws I1Exception, I2Exception {
    throw new I1Exception();        
}
Run Code Online (Sandbox Code Playgroud)

与两个接口不兼容,因为它声明了比每个接口的任何一个方法更多的已检查异常,单独使用.

这意味着我不明白这本书的内容或者这是否意味着书中的陈述是真空的?

lex*_*ore 5

在给出第二个想法之后,我认为本书的目的是要说你必须同时满足这两个接口.

因此,该方法应抛出(粗略地说)两种方法的异常集合的交集.如果这些集合不相交,则该方法不能抛出任何东西.所以这:

@Override
public void x() {
}
Run Code Online (Sandbox Code Playgroud)

两个接口都可以.

(由于继承,它有点复杂,但你明白了.)

所以从我的角度来看

"如果在2个或更多接口中声明了一个方法,并且该方法声明在throws子句中抛出不同的异常,则实现应列出所有这些异常"(第347页)

不能正确,因为它在实践中不起作用.您(在大多数情况下)无法在实现中列出所有这些异常.有一些例外,例如未经检查的异常或相同/兼容的异常集.

但是我无法在JLS中找到规范参考.


Nan*_*ana 4

书上的那句话似乎是不正确的。Java语言规范有更合理的条款解释这个问题(我认为这是本书引用的部分)。

\n\n
\n

当涉及接口时,多个方法声明可能会被单个覆盖声明覆盖。在这种情况下,重写声明必须具有与所有重写声明 (\xc2\xa79.4.1) 兼容的 throws 子句

\n
\n\n

因此在这种情况下,与这两种声明兼容的声明将是

\n\n
@Override\npublic void x() {\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

两个声明都有共同的例外情况,它们可以包含在声明中。

\n\n
interface I1 {\n    public void x() throws I1Exception, I2Exception;\n}\n\ninterface I2 {\n    public void x() throws I2Exception;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后

\n\n
@Override\npublic void x() throws I2Exception {\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者在你的例子中,如果你有类似的东西

\n\n
class I1Exception extends I2Exception {\n}\n\nclass I2Exception extends Exception {\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

那么兼容的方法声明可以写成

\n\n
@Override\npublic void x() throws I1Exception {\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n