学习笔记——异常的捕获及处理(处理流程、throw与throws、处理模型、RuntimeException、自定义异常类、assert断言)

认识异常对程序的影响

Java语言最强大的支持在于异常处理。异常是指中断程序执行的指令流
例子:产生异常

public class Yichang {
public static void main(String[] args) {
	System.out.println(10/0);
    System.out.println("1234");
  }
}

运行结果:
Exception in thread “main” java.lang.ArithmeticException: / by zero
at Yichang.main(Yichang.java:4)
当程序没有异常时,代码按照指令步骤执行。当存在异常时编译程序就会出现错误。出现错误之后程序就会中断执行。异常机制为了避免程序出现非致命错误导致程序中断执行


处理异常

在Java中进行异常处理,可以使用:try、finally、catch这几个关键字来完成,其基本处理结构如下:
在这里插入图片描述
此结构中可以使用的组合有三种:try…catch; try…finally; try…catch…finally。
例子:对以上程序进行处理异常

public class Yichang {
public static void main(String[] args) 
{
	try{
	System.out.println(10/0);
	}catch(ArithmeticException x){
		System.out.println(x);
	}
    System.out.println("1234");
    }
}

输出结果:
java.lang.ArithmeticException: / by zero
1234
此时即使出现了异常,但是程序可以跳过异常继续执行。但是有一个问题,此时的提示信息对于错误排查不方便。为了获得完整的异常信息,则可以利用异常类中提供的printStackTrace()方法。
例子:获取完整异常现象

public class Yichang {
public static void main(String args[]) {
	try{ 
		System.out.println(10/0);
	}
	catch(ArithmeticException x) {
		x.printStackTrace();
	}
	System.out.println("1234");
	}
}

输出结果:
java.lang.ArithmeticException: / by zero
at Y.Yichang.main(Yichang.java:5)
1234
例子:对于异常处理也可以追加一个finally程序块,不管是否产生异常,程序中finally都执行。

public class Yichang {
public static void main(String[] args) 
{
	System.out.println("xfak,wa");
	try{
	System.out.println(10/0);
	}catch(ArithmeticException x){
		x.printStackTrace();
	}finally{
		System.out.println("jyxx,pp");
	}
	}
}

输出结果:
xfak,wa
java.lang.ArithmeticException: / by zero
at Yichang.main(Yichang.java:6)
jyxx,pp


处理多个异常

程序在执行过程中可能产生许多异常,这种情况下需要使用多个catch捕捉异常。
例子:

public class Yichang {
public static void main(String[] args) 
{
	System.out.println("xfak,wa");
	try{
		int x =Integer.parseInt(args [0]);
		int y =Integer.parseInt(args [1]);
	System.out.println(x/y);
	}catch(ArithmeticException x){
		x.printStackTrace();
	}finally{
		System.out.println("jyxx,pp");
	}
	}
}

此时执行程序会出现三类异常;

1·【未处理】程序执行过程时没有输入初始化参数;

[1]xfak,wa
[2]jyxx,pp
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
    at Yichang.main(Yichang.java:6)

2·【未处理】输入的数据不是数字;

[1]xfak,wa
[2]jyxx,pp
Exception in thread "main" java.lang.NumberFormatException: For input string: "a"
    at Yichang.main(Yichang.java:6)

3·【已处理】输入的被除数为零; [1]xfak,wa

java.lang.ArithmeticException: / by zero
    at Yichang.main(Yichang.java:8)
[2]jyxx,pp
[3]sgg,la

即使有了异常处理语句,但是没有正确捕获异常,程序也会异常中断,finally仍然执行。
例子:多异常处理

public class Yichang {
public static void main(String[] args) 
{
	System.out.println("[1]xfak,wa");
	try{
		int x =Integer.parseInt(args [0]);
		int y =Integer.parseInt(args [1]);
	System.out.println(x/y);
	}catch(ArithmeticException x){
		x.printStackTrace();
	}catch(ArrayIndexOutOfBoundsException x){
		x.printStackTrace();
	}catch(NumberFormatException x){
		x.printStackTrace();
	}finally{
		System.out.println("[2]jyxx,pp");
	}
	System.out.println("[3]sgg,la");
	}
}

异常处理流程

在这里插入图片描述
1、在程序运行过程中才会产生异常,一旦产生异常后将自动进行异常实例化对象;
2、若此时程序中没有提供异常支持,则进行异常打印,中断程序执行;
3、若此时程序中存在异常处理支持,那么产生的异常实例化对象会被try捕获;
4、try捕获到异常后与catch中异常类型以此对比,如此时匹配到相应异常处理,则用此catch进行异常处理;
5、如果没有匹配到任何异常处理catch,则检测是否有finally;
6、如果没有finally,则打印异常信息,中断执行。如果存在finally,则执行finally之后打印异常现象,中断程序执行。
异常处理程序之中最大的类型为Throwable,而打开Throwable可以发现存在以下两个子类:
·Error:此时程序还未执行出现的错误,开发者无法处理;
·Exception:程序中存在的异常,开发者可以处理。
通过分析发现,异常产生时候会产生异常实例化对象,异常转换可以向父类转型,实际上所有的异常都可以通过Exception处理。
例子:简化异常处理

public class Yichang {
public static void main(String[] args) 
{
	System.out.println("[1]xfak,wa");
	try{
		int x =Integer.parseInt(args [0]);
		int y =Integer.parseInt(args [1]);
	System.out.println(x/y);
	}catch(Exception x){
		x.printStackTrace();
	}finally{
		System.out.println("[2]jyxx,pp");
	}
	System.out.println("[3]sgg,la");
}
}

输出结果:
[1]xfak,wa
java.lang.ArrayIndexOutOfBoundsException: 0
at Yichang.main(Yichang.java:6)
[2]jyxx,pp
[3]sgg,la
多个异常同时处理时,捕获范围大的放后面。当不确定产生何种异常时候,如果无法确定异常,则可以使用此方法。但是如果程序模块较多,调式程序时候不管发生何种异常总是打印相同的异常信息,无法具体确认异常位置。


throws关键字

在程序执行过程中可能产生异常,但是如果说定义了一个方法,应该明确告诉使用者这个方法会产生何种异常。那么此时在方法声明上可以使用throws关键字进行异常类型标注
例子:观察throws使用

class A{
public static int div(int x,int y)throws Exception{
  return x/y;
    }
}
public class Yichang {
public static void main(String[] args) {
	try{
	System.out.println(A.div(10,0));
	}catch (Exception x){
	x.printStackTrace();
	}
  }
}

输出结果:
java.lang.ArithmeticException: / by zero
at A.div(Yichang.java:3)
at Yichang.main(Yichang.java:9)

主方法也是方法,主方法也可以向上抛出异常。
例子:主方法抛出异常

class A{
public static int div(int x,int y)throws Exception{
return x/y;
	}
}
public class Yichang {
public static void main(String[] args) throws Exception{
	System.out.println(A.div(10,0));
    }
}

此时不再处理异常,编译过程中如果出错由默认方式进行处理。如果主方法继续向上抛出异常,则有JVM负责处理。


throw关键字

此关键字主要作用在于手工进行异常抛出处理。
例子:观察throw使用

public class Yichang {
public static void main(String[] args) {
	try{ //异常对象不再由系统生成,手工定义
	  throw new Exception("123456789");
	}catch(Exception e){
	e.printStackTrace();
	}
    }
}

输出结果:
java.lang.Exception: 123456789
at Yichang.main(Yichang.java:4)

throw与throws区别
1·throw是在代码块中使用的,主要是手工进行异常对象抛出;
2·throws是在方法定义上使用的,表示将此方法中可能产生的异常明确告诉给调用处,由调用出进行异常处理。


异常处理模型

定义一个出发运算方法,具体要求如下:
·在进行数学计算开始与结束时候会有信息提示;
·如果在进行计算过程中产生了异常,则要交给调用处来出来。

class A{
public static int div(int x,int y) throws Exception{
int temp = 0;
System.out.println("开始计算");
try{
temp = x/y; //出现异常,此处中断
}catch(Exception e){
	throw e;//向上抛异常对象
}finally{
System.out.println("结束计算");
  }
return temp;
}
}
public class Yichang {
public static void main(String[] args) {
	try{ 
        System.out.println(A.div(10,0));
	}catch(Exception e){
	e.printStackTrace();
	}
}
}

输出结果:
开始计算
结束计算
java.lang.ArithmeticException: / by zero
at A.div(Yichang.java:6)
at Yichang.main(Yichang.java:18)
对于此类操作可以简化,省略catch与throw操作。

class A{
public static int div(int x,int y) throws Exception{
int temp = 0;
System.out.println("开始计算");
try{
temp = x/y; //出现异常,此处中断
}finally{
System.out.println("结束计算");
    }
return temp;
    }
}
public class Yichang {
public static void main(String[] args) {
	try{ 
        System.out.println(A.div(10,0));
	}catch(Exception e){
	e.printStackTrace();
	}
  }
}

输出结果同上。


RuntimeException

例子:观察 RuntimeException 异常继承结构。
在这里插入图片描述
为了方便代码编写,提供了一个可选的异常处理父类“RuntimeException”,该类的子类可以不需要强制性处理。
例子:抛出Exception 异常

class A{
public static int div(int x,int y)throws Exception{
return x/y;
	}
}
public class Yichang {
public static void main(String[] args) {
	System.out.println(A.div(10,0));
   }
}

Yichang.java:8: 错误: 未报告的异常错误Exception; 必须对其进行捕获或声明以便抛出
System.out.println(A.div(10,0));
在这里插入图片描述
例子:抛出RuntimeException 子类异常

class A{
public static int div(int x,int y)throws ArithmeticException{
return x/y;
  }
}
public class Yichang {
public static void main(String[] args) {
	System.out.println(A.div(10,0));
  }
}

Exception in thread “main” java.lang.ArithmeticException: / by zero
at A.div(Yichang.java:3)
at Yichang.main(Yichang.java:8)

** RuntimeException与 Exception区别?列举常见 RuntimeException异常。**
· RuntimeException是 Exception的子类;
· RuntimeException标注的异常不需要进行强制处理,Exception异常必须强制处理。
·列举: NumberFormatException,ClassAastException,NullPointException.


自定义异常类

Jdk提供的大量异常类型未必够使用,这个时候考虑自定义异常类。自定义异常有两种操作方法:继承Exception、继承RuntimeException
例子:观察自定义异常

class A extends Exception{ //定义异常A
public A(String a){
super(a);
	}
}
class Food{
public static void eat(int num) throws A{
if (num>100){
	throw new A("再吃就胖了");
  }else{
   System.out.println("请继续使用");
  }
	}
}
public class Yichang {
public static void main(String[] args) throws Exception{
	Food.eat(110);
   }
}

输出结果:
F:\Java学习\bao>java Yichang
Exception in thread “main” A: 再吃就胖了
at Food.eat(Yichang.java:9)
at Yichang.main(Yichang.java:17)


        at Yichang.main(Yichang.java:17)

assert断言

**断言功能是指确定代码执行到某行之后是所期待的结果。**这种断言不一定是准确的,但是这种偏差不影响程序正常执行
例子:断言的使用

public class Yichang {
public static void main(String[] args) throws Exception{
	int x=100;
	assert x==101 :"x值不是101";
	System.out.println(x);
  }
}

输出结果:100
程序正常编译执行,此时断言没有被采纳,不影响程序正常执行。在Java中并没有将断言设置为一个必须执行步骤,需要特定环境才能执行。若要想产生断言效果,必须在程序执行过程加入参数。
执行语句:java -ea Yichang
显示结果:Exception in thread “main” java.lang.AssertionError: x值不是101
at Yichang.main(Yichang.java:4)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值