繁体   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