当前位置: 首页 > 面试题库 >

Java样式:正确处理异常

储俊英
2023-03-14
问题内容

我一直在概念上为我的项目决定异常处理结构。

假设您有一个示例

public abstract class Data {
   public abstract String read();
}

还有两个子类FileData和StaticData,它们从某些指定的文件中读取数据,StaticData仅返回一些预定义的常量数据。

现在,在读取文件时,可能会在FileData中引发IOException,但是StaticData将永远不会抛出。大多数样式指南建议在调用堆栈上传播Exception,直到有足够的上下文可以有效处理它为止。

但是我真的不想在抽象的read()方法中添加throws子句。为什么?因为数据和使用它的复杂机器对文件一无所知,所以它对数据一无所知。此外,可能还有其他Data子类(以及更多子类)永远不会抛出异常并完美地传递数据

另一方面,IOException是必需的,因为如果磁盘不可读(或某些此类),则 必须
引发错误。因此,我看到的唯一出路是捕获IOException并在其位置抛出一些RuntimeException。

这是正确的哲学吗?


问题答案:

你是对的。

异常应该与所使用的抽象级别相同。这就是自Java 1.4
Throwable开始支持异常链接的原因。例如,对于使用数据库的服务或与“存储”无关的服务,都没有必要抛出FileNotFoundException。

可能是这样的:

public abstract class Data {
   public abstract String read() throws DataUnavailableException;
}

class DataFile extends Data { 
    public String read() throws DataUnavailableException {
        if( !this.file.exits() ) {
            throw new DataUnavailableException( "Cannot read from ", file );
         }

         try { 
              ....
         } catch( IOException ioe ) { 
             throw new DataUnavailableException( ioe );
         } finally {
              ...
         }
 }


class DataMemory extends Data { 
    public String read()  {
        // Everything is performed in memory. No exception expected.
    }
 }

 class DataWebService extends Data { 
      public string read() throws DataUnavailableException {
           // connect to some internet service
           try {
              ...
           } catch( UnknownHostException uhe ) {
              throw new DataUnavailableException( uhe );
           }
      }
 }

请记住,如果您在编程时考虑到继承,则应针对特定方案进行仔细设计,并使用这些方案测试实现。显然,编写通用库比较困难,因为您不知道如何使用它。但是,大多数情况下,应用程序都局限于特定的领域。

您的新异常是运行时还是已检查?这取决于一般规则是抛出运行时错误并检查可恢复条件。

如果可以通过正确编程避免异常(例如NullPointerException或IndexOutOfBounds),请使用运行时

如果异常是由于程序员无法控制的某些外部资源(例如,网络已关闭)引起的,并且可以执行某些操作(在5分钟内显示重试消息等),则应使用已检查的异常。

如果该异常不受程序员的控制,但是可以执行NOTHING,则可以使用RuntimeException。例如,您应该写入文件,但是该文件已被删除,并且您无法重新创建或重试该文件,则该程序很可能在运行时失败(您无能为力)。

请参见有效Java中的以下两项:

  • 将检查的异常用于可恢复的条件,将运行时异常用于编程错误
  • 抛出适合抽象的异常

我希望这有帮助。



 类似资料:
  • 问题内容: 从历史上看,我总是这样编写我的异常处理代码: 但是最近,出于可读性和懒惰的原因,我开始这样做: 我将光标(jdbc句柄,无论如何)的赋值从try-catch-finally块中分配出来是错误的吗? 除非JVM实际上在分配上爆炸,否则在分配和try块中任何内容的第一行之间,我不确定我的旧样式是否会带来任何额外的价值,而第二种肯定更易读和简洁。文献通常总是采用第一种风格。 编辑 -假设我很

  • 本文向大家介绍Java中断异常的正确处理方法,包括了Java中断异常的正确处理方法的使用技巧和注意事项,需要的朋友参考一下 处理InterruptedException 这个故事可能很熟悉:你正在写一个测试程序,你需要暂停某个线程一段时间,所以你调用 Thread.sleep()。然后编译器或 IDE 就会抱怨说 InterruptedException 没有抛出声明或捕获。什么是 Interru

  • 我对MongoDB Java驱动程序(使用3.0.4版本的驱动程序和3.2.3版本的MongoDB)有一个问题。我正在尝试检查是否有连接打开到MongoDB服务器,如果没有打开,则抛出异常。我应该可以抓住它: 我遇到的问题是抛出的异常没有被捕获,它似乎来自一个我无法访问的线程?对于测试,我没有运行Mongo服务器来查看抛出的异常。与本问题中的问题类似(MongoDB java driver 3.0

  • 问题内容: 我现在正在做一些React,我想知道是否有一种“正确的”方式来进行条件样式设计。在本教程中,他们使用 我不想使用内联样式,因此我想使用一个类来控制条件样式。一个人将如何以React的思维方式来实现这一目标?还是应该只使用这种内联样式方式? 问题答案: 如果您更喜欢使用类名,请务必使用类名。 您可能还会发现类名称包很有用。有了它,您的代码将如下所示: 没有“正确”的方法来进行条件样式设计

  • 假设我有一个类Person,具有不同数据类型的不同属性,我在我的主方法中有这样的代码: 现在,假设高度的赋值引发了一个异常,例如InvalidCastException,代码将停止执行,并且可能会记录一些东西,以防我有一个记录表。问题是,从日志中,我无法确切地理解哪一行和赋值抛出了异常。 是否有任何方法可以捕获异常,并能够记录(数据库中的某个位置)哪个赋值引发异常,以及在这种情况下针对哪种类型的强

  • 寻找一个java正则表达式函数,如果数组元素列表中的特殊字符出现在前面或后面,则返回true 2-返回False如果任何alpha字符之前和之后从我的数组元素列表我的数组元素wordsList={"TIN","tin"}输入: 1-CardTIN是1111 2-Card-TIN:2222 3-cardtinis3334-Card@TIN@4444 5-CardTIN@55556-TINis9999