十四、《异常机制》

1、异常的概念

(来自百度)在 java 中把导致程序中断运行的情况分为两种,一种就是异常,而另外一种叫做错误。所有异常的基类是Exception,错误的基类是Error。Exception是在java程序中可以编码进行控制的,具有可编程性,而Error是指Java运行时系统来显示与运行时系统本身有关的错误,Error对于程序员来说是灾难性的,程序无法控制,比如jvm堆栈溢出错误,操作系统分配内存错误等。不管是Exception还是Error,他们的共同父类是java.lang.Throwable(可抛出的) 类。

异常是指在程序运行期可能出现的非正常情况,这些情况将导致程序出错,这种出错不同于代码编写错误或程序算法出错,代码编写错误无法完成编译,而程序算法出错计算将取得错误的结果。程序出现异常时,缺省会直接造成程序的中断运行,提前预知这种异常的可能性可以补充异常处理的逻辑,从这个角度出发,异常也是一种行之有效的逻辑处理机制,在程序中声明异常或主动抛出异常也很常见。

简而言之,为了提高程序的健壮性,异常需要由程序员处理。

2、什么是Java中的异常

  1. 代码正常运行不会出问题,但是遇到意外,参数变量,不符合要求,发生意外,代码终止运行
  2. 代码中的异常处理好了,代码就可以顺利的继续运行!

3、先看看什么是异常

System.out.println(1/0); // java.lang.ArithmeticException: / by zero
String str = null;

System.out.println(str.length()); // java.lang.NullPointerException
int[] arr = {1,2};

System.out.println(arr[arr.length]); // java.lang.ArrayIndexOutOfBoundsException: 2

SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd HH时mm分ss秒 E");
sdf.parse("fsdfsdf"); // ParseException

4、异常的体系结构

5、异常的处理方式

5.1、自己处理[捕获异常]

   1.try-catch的语法结构及链式结构多异常处理方式

try{

        //可能产生异常的代码

}catch( 捕获的异常类型 e ){ //e是形式参数

        //该异常捕获之后要做的操作

}catch( 捕获的异常类型 e ){ //e是形式参数

        //该异常捕获之后要做的操作

}finally{

        //异常发生之后一定会执行到的语句块:①流资源关闭②释放锁

}

语句块执行顺序:

  1. 顺序执行:进入异常捕获语句块
  2. 如果产生异常,执行catch捕获,捕获到对应异常,并且对应catch后面的代码块
  3. finally语句块一定会执行到:前提前面语句没有执行System.exit(0)退出虚拟机

5.2、异常信息处理方式二抛出异常

语法结构:方法后面使用throws 需要抛出的异常类型

示例:

public static void main(String[] args) throws Exception{ // 抛出了异常
		new SimpleDateFormat().parse("fsfsdfsdf");
}

抛出异常的注意事项:

  1. 方法抛出运行时异常,在方法头可以不用抛出异常
  2. 方法抛出编译时异常:方法必须处理异常,或者抛出同类异常,或者抛出异常该异常的父类类型异常

6、获得异常信息的方式

6.1异常捕获分析

  1. 写多个捕获异常的语句块,链式结构捕获多异常,根据不同的异常,做不同的处理
  2. 捕获异常可以写异常的父类,也可以捕获到对应子类的异常
  3. catch(捕获的异常类型 e)捕获的异常实际捕获一个异常对象,该对象e可以在catch语句块直接使用

6.2、获取信息的方式

方式1:   System.out.println(e);

方式2:   System.out.println(e.getMessage());

方式3:   e.printStackTrace(); // 获取并打印异常信息最常用的方式

7、finally结构

7.1、finally语句块介绍

  1. try-catch语句块可以用写finally处理异常之后finally语句块一定会执行到
  2. finally语句块中,一般用来处理什么内容
    1. 关闭流资源
    2. 释放锁

7.2、注意事项 :

  1. 一般不要在finally里面写返回语句,程序难理解
  2. finally语句之前,如果有执行退出虚拟机,也是不会执行finally语句块
public static void main(String[] args) {
	System.out.println(get(0));
}


public static int get(){
	int i = 10;
	try { // 只在try写返回值:只看结构不看值:报错没有返回语句
		System.exit(0);
		i = 20;
		return i; // 结束方法,返回值
	} catch (Exception e) {
		i = 30;
		return i; // 存在finally语句块,虽然return叫做结束方法,但是其实还没有完全结束  ,变量i,返回值,处于一个缓存的状态
	} finally { // finally先执行,后面才执行的return
		i = 40; // 等于覆盖了返回值变量里面存的值
		return i;    // 修改的返回值的缓存
	}
}

8、主动抛出异常

8.1、为什么需要主动抛出异常

8.2、主动抛出异常示例

        方法内部主动创建异常抛出:throw new SelfException("账户已经存在,请重新输入");

账号登陆示例:

static String[] names = {"XX","OO"};
public static void main(String[] args) {
	login("XX");
}
public static void login(String name){
	for (String string : names) {
		if(name.equals(string)){ // 已经存在一个意外的情况了
//意外情况,主动产生一个异常信息
			throw new NullPointerException("阁下账号已经被人使用");	
	    }
	}
	System.out.println("恭喜您:"+name+"账号可以使用");
}

9、自定义异常

9.1、为什么需要自定义异常:

        1、java已经写好很多异常,但不能满足开发中所有异常描述的需求,所以需要自定义异常

9.2、自定义异常的方式

  1. 自定义类继承异常类
  2. 参照其他异常通过Exception设置异常提示信息
    public class SelfException extends Exception{
    	SelfException(String msg){
    		super(msg);
    	}
    }

9.3、自定义异常使用

static String[] names = {"周周","皇皇"};

public static void main(String[] args) throws SelfException {
	login("周周");
}

public static void login(String name) throws SelfException{
	for (String string : names) {
		if(name.equals(string)){ // 已经存在一个意外的情况了
			throw new SelfException("XXXXXX"); // 意外情况,主动产生一个异常信息
		}
	}
	System.out.println("恭喜您:"+name+"账号可以使用");
}

9.4、throws 和 throw的区别

9.4.1、throws 处理异常

  1. 在方法头抛出异常

9.4.2、throw 抛出异常

  1. 开发代码存在意外的情况,自己主动抛出异常[产生异常]
  2. 在方法内部 throw new NullPointException();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值