论坛首页 Java企业应用论坛

Java 接口的异常设计疑惑

浏览 13567 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-11-11   最后修改:2009-11-16

疑惑1:在设计接口的时,对于接口方法何时需要声明抛出受检异常或者说所有的接口方法最后都声明抛出受检异常?
      
       public interface xx{
              public void method();
       }

       public interface xx{
             public void method() throws Exception;
       }

 

      
      
疑惑2:如果需要声明抛出受检异常,那是抛出一个抽象的异常呢;还是抛出多个具体的异常?

       a,抛出具体异常:

         public interface xx{
               public void method() throws SpecificException1,SpecificException2,...;
         }

         ps:如果要抛出具体异常那就要考虑全部可能的实现类会抛出的异常,我想这样几乎不可能吧。

       b,抛出抽象的异常。如果是这样那是抛出自定义抽象异常呢,还是直接抛出Exception?

         自定义抽象异常:

           public interface xx{
                public void method() throws CustomAbstractException;
           }

         直接抛出Exception:

           public interface xx{
                public void method() throws Exception;

           }

 

     大家说说看到底如何做比较合理?理由是什么?

 

   发表时间:2009-11-11  
接口就是约定,异常是返回结果之一。

对于系统性异常,例如网络可能中断,未知的程序错误等等,这种处理成运行时异常,不作申明比较好,反正接收的人也没办法做任何处理

对于有业务性的错误,例如取款时,余额不够、权限不够、超出最大取款限制等等,这类错误,最好,每个场景,定义一个异常,在申明中逐一说明,总之,异常是帮助使用者了解、处理不同的错误场景。使用者可以根据错误类型的不同,给用户提供不同的处理方式和流程。当然,如果你提供给用户的只是提示信息,就没必要再区分类型了

异常处理方式上,还有一个办法是对异常编码,那就只需要一种类型了,类似SqlException。两种方式都可行,重点是要让约定更加明确、翔实
2 请登录后投票
   发表时间:2009-11-11  
我认为,接口需要抛出异常的时候就抛出异常啊(好像等于没说...)
    接口方里抛出异常应该抽像好点,就是大范围的异常,那么实现这个接口的类方法就可以抛出比这个接口抛出的异常稍小的异常,因为不是每个实现类所抛出的异常都相同.
  这和继承类的方法异常一样,子类的方法抛出的异常不能大于父类方法的异常.(就是进化咯,子类比父类进化得高级一些,不能比父类的异常还多吧.)
0 请登录后投票
   发表时间:2009-11-11  
joachimz 写道
接口就是约定,异常是返回结果之一。

对于系统性异常,例如网络可能中断,未知的程序错误等等,这种处理成运行时异常,不作申明比较好,反正接收的人也没办法做任何处理

对于有业务性的错误,例如取款时,余额不够、权限不够、超出最大取款限制等等,这类错误,最好,每个场景,定义一个异常,在申明中逐一说明,总之,异常是帮助使用者了解、处理不同的错误场景。使用者可以根据错误类型的不同,给用户提供不同的处理方式和流程。当然,如果你提供给用户的只是提示信息,就没必要再区分类型了

异常处理方式上,还有一个办法是对异常编码,那就只需要一种类型了,类似SqlException。两种方式都可行,重点是要让约定更加明确、翔实



    我觉得对于使用不同的异常区分不同错误的情况,在方法声明中抛出所以可能的异常,只有在具体的实现类(非接口实现类或接口只有一个实现类的情况)中比较可行;在接口有多个不同的实现类时,不同的实现又可能抛出不同的异常,这样就无法在接口声明中将这些具体异常全部声明出来了,这时候使用一个抽象的异常就比较可行了。可是如果这样的话,我觉的使用接口的地方,就无法明确到底会出现哪些具体的异常了。这样貌似异常的使用原则(尽量指定具体的异常)有些相违背了。

    还有如果在接口中声明了抛出自定义的抽象异常,那么在实现类中将一些如例如网络可能中断,未知的程序错误等等,这种处理成运行时异常,是将其转译呢,还是直接抛到上异常。
0 请登录后投票
   发表时间:2009-11-12  
czpsailer 写道
joachimz 写道
接口就是约定,异常是返回结果之一。

对于系统性异常,例如网络可能中断,未知的程序错误等等,这种处理成运行时异常,不作申明比较好,反正接收的人也没办法做任何处理

对于有业务性的错误,例如取款时,余额不够、权限不够、超出最大取款限制等等,这类错误,最好,每个场景,定义一个异常,在申明中逐一说明,总之,异常是帮助使用者了解、处理不同的错误场景。使用者可以根据错误类型的不同,给用户提供不同的处理方式和流程。当然,如果你提供给用户的只是提示信息,就没必要再区分类型了

异常处理方式上,还有一个办法是对异常编码,那就只需要一种类型了,类似SqlException。两种方式都可行,重点是要让约定更加明确、翔实



    我觉得对于使用不同的异常区分不同错误的情况,在方法声明中抛出所以可能的异常,只有在具体的实现类(非接口实现类或接口只有一个实现类的情况)中比较可行;在接口有多个不同的实现类时,不同的实现又可能抛出不同的异常,这样就无法在接口声明中将这些具体异常全部声明出来了,这时候使用一个抽象的异常就比较可行了。可是如果这样的话,我觉的使用接口的地方,就无法明确到底会出现哪些具体的异常了。这样貌似异常的使用原则(尽量指定具体的异常)有些相违背了。

    还有如果在接口中声明了抛出自定义的抽象异常,那么在实现类中将一些如例如网络可能中断,未知的程序错误等等,这种处理成运行时异常,是将其转译呢,还是直接抛到上异常。


是否需要使用抽象异常,与你的设计详细程度,接口特性都有关系。
如果你的接口是一个通用接口,你考虑更多的是灵活性与稳定性,当然选择定义一个通用的异常。但如果你是一个专用接口,尽量细化异常,枚举所有场景。设计必须考虑全部场景,实现的时候不会有更多场景,否则就是设计没有考虑完整。

运行时异常是否要处理的判断标准是,如果你不做任何处理,使用接口的人也无能为力。转译是多此一举,连catch都没必要
0 请登录后投票
   发表时间:2009-11-12  
接口的受检异常是在你可以在上层进行恢复的情况下才向上抛的,如果接口产生的异常是不能恢复的,我建议是转换成运行期异常,然后在最上层(action 层) 进行统一拦截,然后进行友好的错误页面的跳转。
不然的话就算你catch 到接口的异常你也没什么办法处理,只能再向上抛了,这样在接口层和上层间的代码就多了很多try 的代码了。
当然像上面的je说的,接口异常也可以作为一种返回值的信号,具体错误,具体处理。。如果你对每个错误没精确的处理的话,抛出Exception 也没问题。。
以上纯属个人理解。。
0 请登录后投票
   发表时间:2009-11-12  
接口是好
但是 也要防止过度设计

业务系统 真的有必要接口都是 可以商榷的

适合简单才是缺憾中的完美
0 请登录后投票
   发表时间:2009-11-12  
抛出异常, 还是捕获异常, 应该对结合当前的任务来看.
如果当前任务能够正确处理异常, 就应该捕获;
否则, 就继续往上抛出.
0 请登录后投票
   发表时间:2009-11-12  
碰到这个问题正是在抛出异常不明确的情况下产生的。
在接口中不声明异常意味着在实现中阻断处理异常。
声明一个独立异常意味着实现无法阻断异常。
而是否在实现中阻断异常是无法猜测的。
thorws Exception是比较折中的做法,不过在使用时还得在外部拦截。
如果实现类外部用户不可控,建议不声明异常。
如果实现类外部提供了可拦截接口,建议throws Exception。
如果实现类内部有明确的异常层次建议设计一个可供继承的异常。
0 请登录后投票
   发表时间:2009-11-12  
    接口就是功能的抽象和约束,我感觉,一般不需要在这样的一个抽象层面上抛出异常,因为你必须考虑一下抛出的异常是所有实现都必须的共性吗?如果你在接口的设计中抛出异常,那么相当于给各种实现套上了一层“枷锁”,而这些受检异常本来可以在更具体的层次上处理的。
    至于抛出的是自定义的异常还是已定义的异常(如 exception),这完全看需要,如果你觉得已定义的异常可以很好的描述该异常,使用已定义异常就可以了;如果你想对异常提供进一步的描述,以便更符合当前的应用,那你可以选择自定义异常。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics