簡體   English   中英

類使用相同的方法實現兩個接口,但不同的檢查異常

[英]Class implements two interfaces with the same method but different checked exceptions

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

}

當然,異常不是方法簽名的一部分,因此編譯器抱怨第二種方法是重復的。

另一方面

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

與兩個接口不兼容,因為它聲明了比每個接口的任何一個方法更多的已檢查異常,單獨使用。

這意味着我不明白這本書的內容或者這是否意味着這本書的說法是無辜的?

在給出第二個想法之后,我認為本書的目的是要說你必須同時滿足這兩個接口。

因此,該方法應拋出(粗略地說)兩種方法的異常集合的交集。 如果這些集合不相交,則該方法不能拋出任何東西。 所以這:

@Override
public void x() {
}

兩個接口都可以。

(由於繼承,它有點復雜,但你明白了。)

所以從我的角度來看

“如果在2個或更多接口中聲明了一個方法,並且該方法聲明在throws子句中拋出不同的異常,則實現應列出所有這些異常”(第347頁)

不能正確,因為它在實踐中不起作用。 您(在大多數情況下)無法在實現中列出所有這些異常。 有一些例外,例如未經檢查的異常或相同/兼容的異常集。

但是我無法在JLS中找到規范參考。

這本書的特定句子似乎是不正確的。 Java語言規范有更合理的條款來解釋這個問題(我認為這是本書所引用的部分)。

當涉及接口時,可以通過單個重寫聲明覆蓋多個方法聲明。 在這種情況下,重寫聲明必須具有與所有重寫聲明兼容的throws子句(第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 {

}

我認為這本書說明你可以選擇你想要實現哪種方法,但不能同時實現它們(沒有嘗試過,但這就是我理解它的方式)。

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

錯誤是在同一個類中有兩個方法具有相同的名稱,沒有參數。 在java中,只有當它們獲得不同的參數時,才能使用相同名稱的不同方法:例如

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

方法可以拋出的已檢查異常集是被聲明的異常集的交集,它被聲明為拋出所有適用的類型,而不是union。 因此,對象上的x()根本不能拋出任何已檢查的異常,並且是允許的。

@Override
public void x() {
}

它說明了多個繼承的throws子句交互,這減少而不是增加允許方法拋出的異常的數量。 這通常不會導致細微的錯誤,但是當你第一次看到它們時它們會有點令人驚訝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM