基本概念
先来讲讲在JAVA中,什么是异常?
Java语言中,将程序执行中发生的不正常情况称为“异常”。
(开发过程中的语法错误和逻辑错误不是异常)<
执行过程中所发生的异常事件可分为两类
1)Error(错误): Java虚拟机无法解决的严重问题。如: JVM系统内部错误、资源
耗尽等严重情况。比如: StackOverflowError[栈溢出]和OOM(out of
memory),Error 是严重错误,程序会崩溃
2)Exception(异常): 其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针
对性的代码进行处理。例如空指针访问,试图读取不存在的文件,网络连接中
断等等,Exception 分为两大类: 运行时异常和编译时异常。<
下面列出异常的分析图
常见运行异常[RuntimeException]
1)NullPointerException空指针异常
2)ArithmeticException数学运算异常
3)ArrayIndexOutOfBoundsException数组下标越界异常
4)ClassCastException类型转换异常
5)NumberFormatException数字格式不正确异常(比如说,判断输入的是不是int类型)
运行异常不用显式处理,有默认处理机制
常见编译异常[Exception]
1.SQLException //操作数据库时,查询表可能发生异常
2.IOException //操作文件时,发生的异常
3.FileNotFoundException //当操作一个不存在的文件时,发生异常
4.ClassNotFoundException //加载类,而该类不存在时,异常
5.EOFException // 操作文件,到文件未尾,发生异常
6.IllegalArguementException //参数异常
编译异常必须显式的处理
异常处理
====try-catch-finally机制====
/** * ====try-catch-finally机制==== * < * try { * (可能有异常的代码) * }catch(Exception e) { * //捕获异常 * //1.当异常发生时,系统将异常封装成Exception对象e,传递给catch * //2.得到异常对象后,程序员自己处理 * //3.注意!!!如果代码无异常,则不会进入到catch * }finally { * //1.不管tru代码块是否有异常,都会执行finally代码块 * //2.通常将释放资源的代码放在finally * } * 《 * 注意:1.可以有多个catch语句,捕获不同的异常(进行不同的业务处理), * 要求父类异常在后,子类异常在前,如果发生异常,只会匹配一个catch[演示] * 2.可以直接try-finally配合使用,这种用法相当于没有捕获异常,因此程序会直接崩掉, * 应用场景,就是执行一段代码,不管是否发生异常,都必须执行某个业务逻辑 */
简单入门
例题:要求输入一个数必须是int类型,否则就反复输入,用异常处理来完成
步骤分析:
1.定义一个整数类型,用于用户输入
2.将输入的字符类型转换为整型
3.try-catch代码,在catch中提示信息
4.设置无限循环,当try不会跳入catch中时,break退出循环
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int num; for (;;) { try { System.out.println("输入一个整数"); num = Integer.parseInt(scanner.next()); break; } catch (Exception e) { System.out.println("输入错误,请输入整数"); } } System.out.println("输入成功,整数为:" + num); }
扩展细节
1.如果try代码块可能有多个异常
2.可以使用多个catch分别捕获不同的异常,相应处理
3.要求子类异常写在前面,父类异常写在后面public class catch扩展演示 { public static void main(String[] args) { try { Person jack = new Person("jack"); jack = null; System.out.println(jack.getName());//NullPointerException空指针异常 int n1 = 10; int n2 = 0; int res = n1 / n2;//ArithmeticException数学运算异常 } catch (NullPointerException e) { System.out.println("空指针异常:" + e.getMessage()); } catch (ArithmeticException e){ System.out.println("数字运算异常:" + e.getMessage()); } catch (Exception e) { System.out.println(e.getMessage()); } } } class Person { private String name; public Person(String name) { this.name = name; } public String getName() { return name; } }
解析:可以看到main类中共有三个catch,分别抓取的是空指针异常[NullPointerException],数字运算异常[ArithmeticException],异常[Exception].
其中,Exception是这两个异常的父类
====throws机制====
1.如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,
则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的
调用者负责处理
2.在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是
方法中产生的异常类型,也可以是它的父类[演示]总结:其实就是往上抛异常,在main方法中,存在一个隐藏的机制
public static void main(String[] args) throws Exception{ }
这里的throws Exception就是往上一级抛异常的意思,main的上一级就是JVM
如果main中有try-catch-finally,那么就没有这个隐藏的机制public static void f1() throws FileNotFoundException, NullPointerException { //创建一个文件流对象 /** * 1.此处是编译异常FileNotFoundException * 2.可以使用throws抛出异常,让调用者处理 * 3.异常类型可以是方法中产生的异常,也可以是父类异常Exception * 4.可以同时抛出多个异常[NullPointerException] */ FileInputStream fis = new FileInputStream("d://aa.txt"); }
扩展细节:
1.对于编译异常,程序中必须处理,比如try-catch或者throws
2.对于运行异常,如果不做处理,那么默认是throws处理
3.子类重写父类方法时,子类所抛出的异常类型要么和父类相同,要么是父类抛出异常类型的子类
4.如果方法中有try-catch,那么就没有throws
throw和throws的区别
throws 是异常处理的一种方式 ,写在方法声明处 ,跟的是异常类型
如:public static void main(String[] args) throws Exception{ }
<
throw 是手动生成异常对象的关键字,写在方法体中 ,跟的是异常对象这里上代码演示
/** * 当我们接收Person对象年龄时,要求范围在 18 - 120 之间,否则抛出一个 * 自定义异常(要求 继承RuntimeException),并给出提示信息 */ public class 应用实例 { public static void main(String[] args) { int age = 200; if (!(age >= 18 && age <= 120)) { throw new custom("年龄错误,需要在 18 - 120 之间"); } System.out.println("年龄正确"); } } class custom extends RuntimeException { public custom(String message) {//接收一个字符串 super(message); } }
解析:
1.定义了一个自定义异常(custom),继承运行异常
2.if语句中,向上抛出一个自定义异常
2.1字符串进入自定义异常后,将字符串调入运行异常中
3.完成语句后,异常信息就会输出该字符串
自定义异常
自定义异常(customException)的步骤:
1.定义类:自定义异常类名,继承Exception或者RuntimeException
2.如果继承Exception则属于编译异常
3.如果继承RuntimeException则属于运行异常,一般继承的都是RuntimeException[可参考上面的代码]