发生异常我们可以使用if-else来堵漏洞,但这样加大工作量,而且堵不完,所以java提供了异常处理机制来解决,提高程序的健壮性
1、异常
(1)什么是异常:异常是指程序运行时发生的不正常现象,异常不是错误
(2)异常会提前结束程序,执行到有异常的地方程序就终止了
2、异常演示
Scanner in = new Scanner(System.in); System.out.println("请输入被除数:"); int a = in.nextInt();//p System.out.println("请输入除数:"); int b = in.nextInt();//0 System.out.println("商为:" + (a / b)); System.out.println("程序结束!");
当数据类型不匹配或者除数为0 时,就会发生异常。
3、异常处理:
(1)使用try-catch块自己处理异常
try{ //代码块1,如果出了问题,会被catch捕获,如果没有出问题,catch块不会执行 }catch(Exception e){ //代码块2,出了问题才会生效,如街上的警察 }finally{ //代码块3,有没有出问题都会执行的, } //代码块4,后续的代码块
使用try-catch块自己处理异常,try块包含可能出现异常的程序段,catch块用来捕获异常并做处理
catch块可以有多个,用来处理不同的异常情况,子异常在前,父异常在后
例如:InputMismatchException是Exception的子类,写的时候写在前,写在后时会报错
public class Test01 { public static void main(String[] args) { try { Scanner in = new Scanner(System.in); System.out.println("请输入除数:"); int a = in.nextInt();//p System.out.println("请输入被除数:"); int b = in.nextInt();//0 System.out.println("商为:" + (a / b)); }catch (InputMismatchException e){ System.out.println("输入类型不匹配异常"); }catch (ArithmeticException e){ System.out.println("算术问题异常"); }catch (Exception e){ e.printStackTrace(); } System.out.println("程序结束!"); } }
注:从出现异常的地方到catch处的程序是不会执行的
在catch块中处理异常的提示信息是为了给用户看的,编程人员看到的应该是异常的报错信息
(2)使用throw和throws抛出异常
throw用来抛出异常,throws用来声明异常,把throw抛出的异常给调用者,由调用者来处理
public class ThrowTest03 { //可能会有异常抛出来,如果有则抛给对应的调用者 public void cal() throws InputMismatchException,ArithmeticException { Scanner in = new Scanner(System.in); int a,b; System.out.println("请输入被除数:"); if(in.hasNextInt()){//判断是否是数字 a = in.nextInt();//p }else{//不是数字则抛出输入类型异常 System.out.println("输入错误,请输入数字!!"); throw new InputMismatchException(); } System.out.println("请输入除数:"); if (in.hasNextInt()){ b = in.nextInt();//0 if (b==0){//如果除数为0,抛出算术问题异常 System.out.println("输入错误,除数不能为0!!"); throw new ArithmeticException(); } }else { System.out.println("输入错误,请输入数字!!"); throw new InputMismatchException(); } System.out.println("商为:" + (a / b)); System.out.println("程序结束!"); } }
谁调用cal()方法,那么异常就抛给谁,由调用cal()方法的调用者来处理异常,同理,调用者也可以再往外抛出。但最终一定要对异常进行处理。所以在程序开发中,尽量少抛出异常,多用try-catch块自己处理
4、finally - return - exit关键字的作用
finally用在try-catch块后,表示最终的,无论都会执行的块
return用在方法中,表示结束方法并返回结果,但是return和finally都存在时,即使有return,finally块也会执行
System.exit()表示结束程序退出,会返回exit()方法中传入的值。如果执行到exit(),那么后面的return和finally都不会执行
优先级:System.exit(0)>finally>return
public class Test02 { public static void main(String[] args) { try { Scanner in = new Scanner(System.in); System.out.println("请输入除数:"); int a = in.nextInt();//p System.out.println("请输入被除数:"); int b = in.nextInt();//0 //System.exit(0);//结束退出并返回0 System.out.println("商为:" + (a / b)); return ;//结束方法,但finally会执行 }catch (InputMismatchException e){ System.out.println("输入不匹配异常"); }catch (ArithmeticException e){ System.out.println("算术问题异常"); }catch (Exception e){ e.printStackTrace(); }finally {//无论如何都要执行的块 System.out.println("无论如何都会执行到"); } System.out.println("程序结束!"); } }
5、常见的异常
异常名 说明 Exception 异常层次结构的根类 ArithmeticException 算术错误情形,如以零作除数 ArrayIndexOutOfBoundsException 数组下标越界 NullPointerException 尝试访问 null 对象成员 ClassNotFoundException 不能加载所需的类 InputMismatchException 欲得到数据类型与实际输入类型不匹配 IllegalArgumentException 方法接收到非法参数 ClassCastException 对象强制类型转换出错 NumberFormatException 数字格式转换异常,如把"abc"转换成数字
6、自定义异常
自定义异常:一个类只要继承了Exception,那么这个类就是自定义异常类
public class Test05MyException extends Exception{ public Test05MyException(){//空构造 super(); } public Test05MyException(String message){//一个参数的构造 super(message); } //int a="";//编译时异常 int a=1/0;//运行时异常 }
7、异常分类
编译时异常:程序写完就报出错误
运行时异常:程序运行时报出错误
8、异常分类结构图
异常分类结构图:
(1)Throwable是类不是接口
(2)Error是系统的错误,不是程序可以解决的,不需要我们处理
(3)Exception是我们可以处理的异常又分为:
a.RuntimeException:运行时异常,用户可以不作出处理,系统会自动处理
9、二维数组
public class Test06 {
public static void main(String[] args) {
//一维数组
int [] arr={1,2,3,4,5};
//二维数组
int [][] list={
{01,02,03,04,05},
{12,22,32,42,52},
{13,23,33,43,53}
};
//二维数组每行的个数可以不一样
int [][] list1={
{01,02,03},
{12,22,32,42,52},
{13}
};
//二维数组声明
int [][] a=new int[5][];
//表示该数组的第一维长度为5,声明二维数组时第一维必须指定长度,现在数组中默认存着5个地址值
int [][] b=new int[5][];
//b[0]=new int[3];//表示第一维的第0位置存着3个0
//二维数组输出
int [][] c=new int[5][3];
for (int i = 0; i <c.length ; i++) {
for (int j = 0; j < c[i].length; j++) {
System.out.print(c[i][j]+"\t");
}
System.out.println();
}
//三维数组
int [][][] d=new int[5][][];
}
}