簡體   English   中英

使用接口隱藏了實現引發的異常

[英]Using interface hides the exception thrown by implementation

給出以下代碼:

interface Provider
{
    String getStuff();
}

class CustomProvider implements Provider
{
    public String getStuff() throws RuntimeException
    {
        // possibly throwing an exception

        return "some stuff";
    }
}

class Main
{
    public static void main(String[] args)
    {
        Main main = new Main();
        main.test(new CustomProvider());
    }

    public void test(Provider provider)
    {
        provider.getStuff(); // we don't know that this can throw an exception!
    }
}

在這種特殊情況下,我們知道,但在其他情況下可能不會。

在接口的實現引發未檢查的異常而客戶端方法不知道接口的具體實現的情況下,我們如何保護自己呢?

似乎有時使用未經檢查的異常,您實際上根本不知道調用方法是否可以引發異常。

一個解決方案是在接口中更改方法的簽名:

interface Provider
{
    String getStuff() throws Exception;
}

這將確保將通知該方法的客戶端在所有實現中都可以引發異常。 這樣做的問題是,也許接口的所有實現都不會實際引發異常。 同樣在接口的每種方法中都放置一個“ throws Exception”(拋出異常)看起來有點怪異。

似乎有時使用未經檢查的異常,您實際上根本不知道調用方法是否可以引發異常。

編譯器不檢查未檢查的異常。 您可以記錄接口的約束,但是編譯器不會自動驗證它們。

您建議聲明該方法引發Exception。 一種更受約束的方法是聲明該方法引發一些已檢查的異常。

例如,您可以明確聲明您的方法可能引發I / O異常,如下所示。 然后,調用者僅需要處理或引發IOException,而不需要更多可能的Exception。

interface Provider
{
    String getStuff() throws IOException;
}

另一種選擇是聲明臨時異常類型。 這允許接口向調用方通告異常協定,而不會限制實現可能遇到的異常類型。

interface Provider
{
    String getStuff() throws ProviderException;
}

class MyProvider implements Provider {
    public String getStuff() throws ProviderException {
       try {
          ...
       } catch ( IOException e ) {
          throw new ProviderException( e );
       }
    }
}

public class ProviderException extends Exception {
    public ProviderException( Exception cause ) {
        super( cause );
    }
    ...
}

暫無
暫無

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

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