java try catch 与 throws 使用场景以及怎么合理使用?

try-catch和throws的区别:

  • try-catch : 在当前位置处理异常

  • throws: (语法格式: 在方法签名之后:throws 异常类型)

    • 向上抛出异常,可以无限向上抛出,直到抛给main方法,main方法就抛给JVM虚拟机去解决。

    • 即比如在3个类中,第3个类出现异常,可向上抛给第二个类,第二个类如果不想解决,可继续抛给第一个类中去解决,然后在第一个类中(调用第三个类中方法会出现异常)==》就使用try-catch解决异常。

相当于throws可以向上指定抛到某一个类里面去集合解决异常(使用try-catch解决异常),而try-catch是直接处理异常。


注意:throws后可以同时抛出多个异常类型

public void 方法名() throws ArithmeticException,NumberFormatException{}

throws 原理:有throws的方法的是所有代码中 , 某行代码创建了异常对象,直接去跟throws后的异常类型匹配,如果匹配不上,则自动匹配下一个,匹配上为止。
i: 如果能匹配上则向上抛出成功,由调用方法的地方来处理
ii: 如果所有的都匹配不上,则抛出失败,由jvm默认处理



对于如下场景,给出不同的看法:

自定义的方法里面java api抛出了异常,这个时候,我是需要捕获呢?还是我也继续往上抛。

比如,我这里定义了一个日期处理的方法,有两种对异常的处理方式,


1、使用throws继续向上抛出异常:

    public static Date convertStringToDate(String dateString, String format) throws ParseException{
        if (org.springframework.util.StringUtils.isEmpty(format)) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.parse(dateString);
    }

2、自己捕获异常

public static Date convertStringToDate(String dateString, String format) {
    if (org.springframework.util.StringUtils.isEmpty(format)) {
      format = "yyyy-MM-dd HH:mm:ss";
    }
    SimpleDateFormat sdf = new SimpleDateFormat(format);
    try {
      return sdf.parse(dateString);
    } catch (ParseException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      return null;
    }
  }



请问,哪种方式,更好一些呢?


看法一:

我倾向于向上抛出异常,因为你这个方法里面的参数是调用者提供的,如果传入的日期有问题,应该让调用者知道,并且捕获进行进一步的处理。比如,如果这个日期是用户设定的,就要通知用户重新设定,如果这个日期是其他输入源提供,就要有一个替代的日期作为标识,表明这个原本输入的日期是错的。


看法二:

对于你这两种方法我有个人看法。

1、继续向上抛出异常

2、自己捕获异常

如果你的第一种方法里。传入开始日期和结束日期。分别操作这两个参数都有可能出现异常。像你这第一种方法抛出,那调用者怎么区分是哪一个日期出了问题呢?你有没有自己想过自己捕获异常之后再抛给调用者呢?
就像你一个方法里,
操作开始日期报错了。catch到Exception里给一个retMsg做区分是开始日期不正确
操作结束日期报错了。catch到Exception里给一个retMsg做区分是结束日期不正确
再将这个具体的Exception抛给调用者。反馈给用户岂不是更加明确了。


看法三:

try catch一般在最上层使用,底层的都使用 throws 向上抛出。如果即在最上层做try catch,又在底层方法做try catch,程序会变的很混乱。一般可预见的错误,比如空指针,你完全可以在最上层比如 controller 层进行判断下,不要让null进入底层方法引起不必要的麻烦,你也省的给底层和上层方法都加预防空指针异常的判断。


看法四:

首先要理解异常到底是个什么

异常其实是程序运行过程中无法预料的事件(这里指非RuntimeException),一旦出现这些事件,你必须要进行处理。比如正在访问 数据库时,
数据库服务器当机,导致你的业务被中断。这种情况下,你的系统至少必须要告诉明确地用户这次业务操作是失败的,而在后台中,应该留下错误日志,以便排除故
障时留下线索。

如何处理异常,这和你的系统设计方案有关

以三层架构(表现层、业务逻辑层、数据访问层)和前面说的数据库访问失败为例,在你的数据访问层提供了方法:

getXXX();
getYYY();

updateXXX(XXX data);
updateYYY(YYY data);
……

对异常的处理你可以

1、在你的数据访问层捕捉异常,如果是 getXXX 方法出现异常,返回null,如果是updateXXX 方法出现异常,返回false,在数据访问层记录事务日志,逻辑层根据数据访问层的返回值进行逻辑处理

2、在数据访问层声明抛出异常,由逻辑层进行统一捕捉,并记录错误日志。同样通过返回值,让表现层来决定提供哪些信息给用户

3、其它方式我不常用,当然系统设计也不会只有三层设计一种方式,就不说了

异常处理是一种策略,一旦确定,则应该进行统一规范,不能让各个程序员过于自由发挥


其他看法:

向上抛,快到前台的时候把控下。

如果知道可能会出错的异常类型,就try catch,并做出相应的处理。。
如果无法预测。。直接throws..

异常处理最忌讳的就是catch后不处理,直接打印一句e.printStackTrace() 这样如果有问题就会隐藏掉,内部的方法调用的时候可以往上抛异常
例如,dao层一个抛给service层,service层再抛给Controller层,Controller层就不要再抛了



来自于http://bbs.csdn.net/topics/391990528

posted @ 2022-03-03 15:19  JourneyHua  阅读(1171)  评论(0)    收藏  举报