zoukankan      html  css  js  c++  java
  • 异常何时抛出?何时自己处理?

    原始问题:

      关于异常中,何时在该类中处理,何时抛给调用类处理,比较纠结。比如IO中new FileInputStream(),new InputStreamReader(fStream, "UTF-8");in.readLine()等他们异常哪些本类中处理,还是都抛给调用者。

    讨论:

      李:其实对于方法中的异常处理有两种方法:1、在该函数中用try...catch语句进行捕获和处理。2、直接抛出异常(这种做法有一点模糊,因为并不能确定该方法是否有异常),那么调用该方法的调用者就要处理这个方法的异常。也就是抛出异常的情况是抛给调用者去解决了。因为try..catch语句如果用的多的话,代码比较繁琐不易观看,所以才会有抛出一种异常这种做法吧 。

      胡:这样写行吗?

      

                FileInputStream fStream = null;
                InputStreamReader reader = null;
                BufferedReader in = null;
                try {
                    fStream = new FileInputStream(path);
                    reader = new InputStreamReader(fStream, "UTF-8");//将InputSteam转换成Reader
                    in = new BufferedReader(reader);    //只提供缓冲区的包装方法
                    //dosomething
                } catch (FileNotFoundException e) {
                    throw e;
                } catch (SecurityException e) {
                    throw e;
                } catch (UnsupportedEncodingException e) {
                    throw e;
                } catch (IOException e) {
                    throw e;
            }finally {
               try{ if (fStream != null) fStream.close();}catch (IOException e){log.warn("FileInputStream close failed");}
               try{ if (reader != null) reader.close();}catch (IOException e){log.warn("InputStreamReader close failed");}
               try{ if (in != null) in.close();}catch (IOException e){log.warn("BufferedReader close failed");}
            }

      李:最好别嵌套写

      胡:还是根本就不拥try

      李: 要用try

      胡:直接抛给调用者。

      李:这个finally里边还有try..catch,就别这样嵌套写了

      胡: 为什么呢? 还是不管什么异常都抛给调用者。 我嵌套,是因为close也抛出异常。  不这样做的话,可能某个流没有被关闭。 所以我特别的纠结,究竟该怎么写,有没有一套规范。

      李: 像这种非运行时的异常直接抛出应该没问题

      胡: 我这样写,我又有点嫌它写的太长了。 

      李: 这样确实很繁琐

      胡:既然要抛出,索性,全部都丢给调用者。 那try也不用了。 

      李: 如果两种异常全部抛出,根据大小关系,调用者来两个catch。能行吗?

      胡:你说的意思我有点模糊

      李:  我还没试过直接抛出两种异常的代码,所以我也不清楚,调用者根据捕获的异常来处理,是否能处理呢? 

      胡: 你这个应该是能不能处理的。毕竟两种异常调用者很难去识别是哪一种异常。

        李:恩,这个有点异议, 调用者应该知道抛出的是哪种异常啊

      胡: 我的意思比如你要抛出io和math异常,那么就用throws Exception来抛出。  调用者接受的是Exception。  这样能识别出是哪种吗? 

      李: 恩,那没抛出math异常,在底层的方法里边应该用try...cathe来捕获math异常啊

      胡: 是的。

      这个问题也不知道怎么回事儿了,待大神解决。

      还有两个问题:

      1、java中垃圾回收器会自动检测不再被引用的对象,之后释放空间。释放空间之后java jvm会不会像C++给指针赋值NULL?而且java jvm快到耗尽的时候才调用垃圾回收机制,如果这时因为某些情况我必须要释放内存,自己定义finalize方法去实现,我怎么保证对象的空间一定被释放掉了?也就是finalize方法不是析构函数,是怎么被调用的?

      2、Chanel可以用于线程间的通信,还有哪些应用场合,有什么好处?

    (邓维佳)回答:

    1.由外界不稳定性导致的异常,应该抛出,比如IO,

    2.考虑出现异常的责任,如果在系统外,抛出

    3.对于异常的处理,如果觉得可能处理不当,应该printstack,同时打印context信息,便于根据日志追查原因

    4.嵌套的trycatch,两层就够了,第一层是主要逻辑,第二层,我觉得更多是语法要求。IO的异常被操作系统屏蔽的很好,除非权限问题,文件不存在,网络不通这类,assign给运维处理一下就能解决。所以不太可能外层try关闭和嵌套层try做同一个事情,一个成功一个不成功

    5.处理异常的原因不仅仅是代码声明可能有异常发生,更主要的是需要考虑,我处理了异常是否合理,如果本身主调方传参有误导致异常,在方法开头就需要check,然后抛异常,对于不合法的请求,我们是没有办法做容错处理的

    6.当然,有些情况的异常,在业务逻辑上是合法的,但是在java语法上不合法,这个时候我们就可以考虑内部处理。比如传一个数字进来,可以使Integer 可能是 String,可能是十进制,可能是十六进制,根据不同格式做相应转换。或者传入一个null,发生异常try掉,然后默认赋值为0.。。。

     7.对于通过父类接受异常,上层框架可以分别异常类型。可以使用 e instanceof RuntimeException 或者e.getCause() 

       

  • 相关阅读:
    Java环境变量的配置
    Vim的使用
    codeforces round506(div3)A. Many Equal Substrings
    codeforces round 531(div3) D. Balanced Ternary String
    codeforces Manthan, Codefest 18 (rated, Div. 1 + Div. 2) D. Valid BFS
    codeforces codefest18(div1+div2) B. Reach Median
    D. Sum in the tree codeforces round#530(div2)
    codeforces round 508(div2) D. Slime
    codeforces goodbye 2018 C. New Year and the Sphere Transmission D. New Year and the Permutation Concatenation
    C. Classy Numbers cf edu round50
  • 原文地址:https://www.cnblogs.com/lijia0511/p/5004601.html
Copyright © 2011-2022 走看看