java 到异常_Java中的异常

异常是程序运行过程过程出现的错误,在Java中用类来描述,用对象来表示具体的异常。 Java将其区分为Error与Exception,Error是程序无法处理的错误,Exception是程序可以处理的错误。 异常处理是为了程序的健壮性。

Thorwable类是所有异常和错误的超类,有两个子类Error和Exception,分别表示错误和异常。 其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常, 这两种异常有很大的区别,也称之为非检测异常(Unchecked Exception)和检测异常(Checked Exception)

下面来通过代码直观地看一下这两者的差别:

检查异常:

7d7cd9de53b9706bc0b53479907865ea.png

如上图所示,如果不对红线所存在的异常进行处理,该代码是无法通过编译的。必须对其进行throws或者try-catch:

34ea83171a0d031cc3ff448b0afe50fa.png

如上图所示,对两个异常进行了try-catch处理,代码可以正常编译。那么这样的异常(FileNotFoundException和IOException)就叫作检查异常,也叫作非运行时异常,意思是在编译前就应该对该异常进行处理,否则无法通过编译。

非检查异常:

0c489eb7a2c9b928b48128d7ea773f4d.png

如上图所示,出现了ArrayIndexOutOfBoundException,这个异常是编译成功,运行时出现的异常,顾名思义,该异常意思是数组角标越界了,由于该异常是在运行时出现的异常,所以此类异常也叫作运行时异常,或非检查异常。类似的异常还有NullPointerException等。

自定义异常:

上面出现的几种异常不管是什么类型,都是Throwable的间接子类,都已经封装完毕,我们直接使用就行,但有时候我们系统根据需求会出现各种各样的异常,这时候就要自定义异常对象了。自定义异常,也是将异常进行封装,说白了就是用一个自定义的类对异常信息进行封装,该类继承Exception,只需要复写父类的构造方法即可,通过super将信息传入到参数。先来看看父类的构造是如何实现的:

Exception:

566d9fe07db1c8a22d09832f42167f35.png

Throwable:

a70c653e9f1cacb7c698042804cbfc7a.png

a2971671f612cabfdba0fecf6878a63f.png

这就很明显了,我们在自定义异常类时,在构造方法中用super调用了该类的父类Exception中的构造方法,并将参数传入,在Exception中用super调用父类Throwable中的构造方法,并将参数传入,并将该实参值赋值给该类的detailMessage属性,在getMessage()方法中获取该值,所以也就有了"myException.getMessage()"(下文会提到)了,可以看得出来这个方法其实是调用的Throwable类中的方法。

假设当前有个需求:对于用户输入的用户名进行检测,如果用户名不是“张三”,则抛出我们自定义的异常对象myException,并打印异常信息。

自定义的异常类:

1 public class MyException extendsException{2

3 private static final long serialVersionUID = 1041819209403514525L;4

5 publicMyException(String message) {6 super(message);7 }8 }

controller层:

1 public classUserController {2 private UserService userService = newUserService();3

4 public User queryUser(String name,String password) throwsMyException {5 returnuserService.queryUser(name,password);6 }7 }

service层:

1 public classUserService {2 private UserDao userDao = newUserDao();3 public User queryUser(String name, String password) throwsMyException {4 returnuserDao.queryUser(name,password);5 }6 }

dao层:

1 public classUserDao {2

3 public User queryUser(String name, String password) throwsMyException {4 if (!"张三".equals(name)) {5 throw new MyException("输入的密码或者用户名错误");6 }7

8 User user = newUser();9 user.setUsername(name);10 user.setPassword(password);11

12 returnuser;13 }14 }

测试:

1 public classTest {2

3 public static voidmain(String[] args) {4 UserController userController = newUserController();5 try{6 User user = userController.queryUser("张大三", "111");7 System.out.println(user);8 } catch(MyException myException) {9 System.out.println(myException.getMessage());10 }11

12 }13 }

如上图所示:在测试类中调用controller中的方法queryUser(String name,String password)来查询用户,该方法内部调用的是service层的queryUser(String name,String password)方法,service中的该方法内部调用的是dao层的queryUser(String name,String password)方法,在dao层的该方法内部,对方法参数进行了判断,如果参数满足某条件就出现异常,将该异常抛出,并在方法声明部分进行throws声明,告知调用该方法的对象,该方法可能存在异常,你要调用,就要对其处理,至于处理的方法取决于调用者,要么直接在方法声明部分throws抛出,交给更上一层,要么进行try-catch,那么当前的调用者是谁呢,调用dao层该方法的是service层,那么service层中只是进行了throws,将异常继续向上抛了,同理,调用service的是controller,controller同样也是进行了throws,那么在测试类Test中调用controller层的方法,进行了try-catch处理,对可能出现异常的代码进行try,如果监听到的异常和catch捕获的异常对象对应,那么就对其处理,此处处理只是简单打印异常信息:

c4d05b6ea44335c4cc4d4f80a693053f.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值