Java学习笔记(八)异常与异常处理

一、异常

1.什么是异常

异常就是一种对象(Exception)java里的异常对象都是派生于Throwable类的一个实例,若java内置的异常类不能够满足需求,用户可以创建自己的异常类。

  • 在程序运行过程中,如果JVM检测出一个不可能执行的操作,就会出现运行时错误
  • java里运行时错误(Runtime Error)会作为异常抛出
  • 如果异常没有被处理,程序将会非正常终止

 

2.处理异常要做什么

处理异常一般有以下用途:

  • 恢复正常的程序执行
  • 进行日志处理
  • 以某些方式提醒用户(错误提示、对话框)

3.异常的分类

异常的层次结构简化图

 

所有的异常都是由Throwable继承而来,并在下一层立即分解为ErrorException

Error类层次结构描述了Java运行时系统的内部错误资源耗尽错误。应用程序不应该抛出这种类型的对象。如果出现了这样的内部错误,除了通告给用户,并尽力使程序安全地终止之外,再也无能为力。

而在设计Java程序时,需要关注Exception层次结构。这个层级结构大致可以分为两个分支:一个是派生于RuntimeException,另一个分支包含其他异常。

由程序错误导致的异常属于RuntimeException,如:

  • 错误的类型转换;
  • 数组访问越界;
  • 访问null指针,

程序本身没有问题,但由于像IO错误这类问题导致的异常属于其他异常,如:

  • 试图在文件尾部后面读取数据;
  • 试图打开一个不存在的文件;
  • 试图根据给定的字符串查找Class对象,而这个字符串表示的类并不存在;

而Java语言规范将派生于Error类或RuntimeException类的所有异常称为非受查异常,其他异常称为受查异常。编译器将会核查是否所有的受查异常提供了异常处理器。(受查异常是我们要求我们自己捕获并处理的,而非受查异常则可省略)

4.异常处理机制

4.1异常处理机制的关键字

  • try:监控有可能产生异常的语句块
  • catch:以合理的方式捕获并处理异常
  • finally:不管有无异常,一定会执行的语句块(一般用来释放资源等)
  • throw:手动引发异常
  • throws:指定由方法引发的异常

4.2 声明受查异常 - throws

如果遇到了无法处理的情况(或不应在这里处理),那么Java的方法可以抛出一个异常,而调用这个方法就必须捕获并处理这个异常或继续向上层抛出异常。(用 throws 抛出的应当是受查异常)如:

public FileInputStream(String name) throws FileNoFoundException, EOFException{

}

注意:

  1. 有 throws 声明异常,但在方法体中,并不一定需要有 throw 抛出相应的异常,这是为异常先占个位置,以后就可以抛出这种异常而不用修改已有的代码。对定义抽象基类接口时,这点很重要。
  2. 如果子类覆盖了父类的已声明的异常的一个方法,那么子类的方法中可以抛出更特定的异常,或者根本不抛异常
  3. 如果子类覆盖了父类没有声明异常的一个方法,那么子类的方法中最好也不要抛出受查异常

4.3 抛出异常 - throw

若在方法体中将会发生异常,可以自己手动抛出,如:

throw new FileNoFoundException;

也可以抛出自己定义的异常,如:

public void setAge(int age) throws Exception{
	if(age < 30) {
		this.age = age;
	}else {
		throw new Exception("年龄过大");
	}
}

4.4 捕获异常  -  try catch finally 语句

异常发生的时候,必须要有一个地方进行捕获,否则将会导致程序终止执行。而捕获异常就需要用到 try-catch-finally 语句块。

其中finally语句块不是必要的,finally语句块里一般用于释放资源。

如:

try {
	System.out.println("可能的异常发生前");
	stu.setAge(50); // 传入大于30即会发生异常
	System.out.println("可能的异常发生后");
} catch (Exception e) {
	e.printStackTrace();
	System.out.println("\n 这里只有捕获了异常才会执行");
}
finally {
	System.out.println("这里是无论是否发送异常都会执行");
}

System.out.println("若未捕获到正catch里的异常,这里不会被执行");
成功捕获异常时控制台的打印
没有发生异常时的控制台打印

 

4.5 捕获多个异常

一个try语句块可以捕获多个异常类型,并对不同类型的异常做出不同的处理。可以按照夏磊方式为每个异常类型使用一个单独的catch子句

try{
	//可能发生异常的地方
}
catch(FileNotFoundException e) {
	//文件未找到的异常处理
}
catch(IOException e) {
	// IO异常的处理
}

若不同异常的处理都是一致的,可合并catch子句

try{

}
catch(FileNoFoundException | UnknownHostException e){

}

4.6 创建异常类

在程序中可能会遇到任何标准异常都没有能够充分描述清楚的问题。在这种情况下,就可以去创建自己的异常类。只需要定义一个派生于Exception的类,或者派生于Exception子类的类。

创建自定义的类,最简单的方式,只需要写两个构造器,一个是默认的构造器,另一个是带有详细描述信息的构造器(超类Throwable 的 toString 方法将会打印出这些详细信息)

class AgeMoreThanThirtyException extends Exception{

    public AgeMoreThanThirtyException(){
    } 

    public AgeMoreThanThirtyException(String message){
        super(message)
    }
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值