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

时间:2014-10-10 13:38:29

标签: java exception-handling

书中" Oracle认证专家Java SE 7程序员考试1Z0-804和1Z0-805综合OCPJP 7认证指南"它由S G Ganesh和Tushar Sharma表示,

  

"如果在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();        
    }

}

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

另一方面

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

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

这意味着我不明白这本书的内容是什么意思,或者这意味着该书的陈述是否真空?

5 个答案:

答案 0 :(得分:5)

在再考虑之后,我认为本书的目的是要说你必须同时满足这两个界面。

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

@Override
public void x() {
}

两个接口都可以。

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

从我的观点来看

  

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

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

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

答案 1 :(得分:4)

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

  

When interfaces are involved, more than one method declaration may be overridden by a single overriding declaration. In this case, the overriding declaration must have a throws clause that is compatible with all the overridden declarations (§9.4.1)

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

@Override
public void x() {
}

在这两个声明中都有一些例外,它们可以包含在声明中。

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

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

然后

@Override
public void x() throws I2Exception {
}

或者在您的示例中,如果您有类似

的内容
class I1Exception extends I2Exception {
}

class I2Exception extends Exception {
}

然后可以将兼容的方法声明写为

@Override
public void x() throws I1Exception {

}

答案 2 :(得分:1)

我认为这本书说明你可以选择你想要实施哪种方法,但不能同时实现它们(没有尝试过,但这就是我对它的理解方式)。

the implementation should list all these exceptions可能意味着一个方法在throws子句中声明的所有异常。

答案 3 :(得分:0)

错误是在同一个类中有两个方法,它们的名称相同,没有参数。 在java中,只有获得不同的参数时,才能使用相同名称的不同方法:例如

public int i (int a);
public int i ();

答案 4 :(得分:0)

  

方法可以抛出的一组检查异常是   声明为的检查异常集的交集   抛出所有适用的类型,而不是联合。   结果,对象上的x()根本不会引发任何检查的异常,并且是允许的。

@Override
public void x() {
}

它说明了 多个继承的throws子句的交互作用,这减少而不是 这通常不会引起细微的错误,但是当您第一次看到它们时,它们可能会令人惊讶。