07_异常处理
一、异常的分类:
大的方面:Error 、 Exception
1.Error: 这种错误 我们一般不处理
public static void main(String[] args) {
int[] arr = new int[1000000000];
}
(内存溢出错误)
2.Exception :才是我们处理的重点:
编译期异常:在编译期间发生的异常(checked Exception)
运行时异常:在编译期无法知道 直到程序运行时才发生的异常 称为运行时异常(unchecked Exception)
1.运行时异常
是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序 员应该积极避免其出现的异常。java.lang.RuntimeException类及它的子 类都是运行时异常。
对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对 程序的可读性和运行效率产生影响。
2.编译时异常
是指编译器要求必须处置的异常。即程序在运行时由于外界因素造成的一 般性异常。编译器要求Java程序必须捕获或声明所有编译时异常。
对于这类异常,如果程序不处理,可能会带来意想不到的结果。
二、常见异常:
throwable 两个直接子类 :error 、exception
java.lang.RuntimeException
ClassCastException
ArrayIndexOutOfBoundsException
NullPointerException
ArithmeticException
NumberFormatException
InputMismatchException
java.io.IOExeption
FileNotFoundException
EOFException
java.lang.ClassNotFoundException
java.lang.InterruptedException
java.io.FileNotFoundException
java.sql.SQLException
1.运行时异常:
ArrayIndexOutOfBoundsException(数组下角标越界异常)
public static void main(String[] args) {
int[] arr = new int[5];
for(int i = 0 ; i < 10;i++) {
System.out.println(arr[i]);
}
}
NullPointerException(空指针异常)
ArithmeticException(算数异常)
public static void main(String[] args) {
int a = 10;
int b = 0;
System.out.println(a/ b);
}
ClassCastException(类型转换异常)
public static void main(String[] args) {
Object obj = new SalariedEmployee();
HourlyEmployee he = (HourlyEmployee)obj;
}
InputMismatchException(输入类型匹配异常)
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
}
2.编译期异常:
ParseException(解析异常)
public static void main(String[] args) {
Date date = new Date();//获取系统当前时间
System.out.println(date);
//对时间进行格式化 将一个Date时间格式化为一个字符串时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String strDate = sdf.format(date);
System.out.println(strDate);
//也可以将一个字符串类型时间解析为Date
String dateStr = "2019-11-11";
Date d =null;
try {
d = sdf.parse(dateStr);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(d);
}
编译期异常和运行时异常的一个区别:
编译期异常必须处理 不处理程序无法运行 处理的重点
运行时异常 可以不处理 但是在运行期间有可能发生异常
但是针对运行时异常 往往可以通过完善代码逻辑来进行避免异常的发生
例如:(运行时异常可以加判断来避免异常)
三、异常的处理机制:
异常对于程序的影响:
1 编译期异常:程序直接导致不能运行
2 运行时异常:将导致程序运行到异常发生处
程序将直接终止运行 而且后续代码都将不再执行。
异常的处理:
方式一:try-catch-finally
方式二:throws + 异常类型
Java中异常的处理模型:抓抛模型
1、try-catch-finally(抓)
try {
有可能发生异常的代码。
}catch(需要捕获的异常的类型 变量){
当发生匹配的异常时候才会执行的代码。
针对捕获到的异常的处理。
}finally{//可选块
无论代码是否发生异常 都需要执行的代码
}
异常中常用的方法:
1.public void printStackTrace()
将此throwable和其追溯打印到标准错误流。 此方法在错误输出流上为该Throwable对象打印一个堆栈跟踪,
该值为字段System.err的值。 第一行输出包含该对象的toString()方法的结果。
剩余行表示先前通过方法fillInStackTrace()记录的数据。
该信息的格式取决于实现,但以下示例可能被认为是典型的:
public class ExceptionDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int i =0;
try{ i = sc.nextInt();
}
catch (InputMismatchException e) {
e.printStackTrace();
System.out.println("发生输入类型不匹配异常 请输入int类型");
}
}
}
2.public String getMessage()
返回此throwable的详细消息字符串。(可能是null)
public class ExceptionDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int i =0;
try{ i = sc.nextInt();
}
catch (InputMismatchException e) {
System.out.println(e.getMessage());
System.out.println("发生输入类型不匹配异常 请输入int类型");
}
}
}
注意:
1.在try。。。catch 可以有多个catch块 将来代码发生那个异常 就执行那个catch的代码
public class ExceptionDemo {
public static void main(String[] args) {
int[] arr = new int[]{ 2 , 5, 6, 0 ,7 ,9};
int sum = 0;
try {
for (int i = 0 ;i < 10 ; i++) {
if(i == 2 ) {
arr = null;
}
sum += arr[i];
System.out.println(sum/arr[i]);
}
} catch (ArithmeticException e) {
System.out.println("发生了算数异常 "+e.getMessage());
}catch (ArrayIndexOutOfBoundsException e) {
System.out.println("发生了数组下标越界异常 " + e.getMessage());
}catch (NullPointerException e) {
System.out.println("发生了空指针异常 " + e.getMessage());
}catch (Exception e) {
System.out.println("发生未知异常 " + e.getMessage() );
}
}
}
2.在catch捕获异常时 首先匹配最精确的异常类型 如果没有具体精确的类型匹配 才匹配父类异常
3.针对多异常的catch 顺序是否有要求:
1 对于Exception的catch 必须位于所有catch的最后
2 同级别的异常 顺序无所谓
3 遵循一个原则 从小到大
4.jdk7及之后的版本 多异常的新写法:
catch (ArithmeticException | ArrayIndexOutOfBoundsException | NullPointerException e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
在上述写法中 不能出现大范围的异常类型(上述写法中 不能出现Exception) 只能时同级别异常类型
5.finally代码块:
finally {
System.out.println("finally 代码块执行....");
}
finally 无论try中的代码是否发生异常都将要执行的代码
(一般用在数据库链接的释放 、 对于文件操作流的关闭等)
6.try-catch-finally三种写法:(try必须有、catch finally可以没有,但是不能全没有)
try。。。catch
try 。。。finally
try 。。。 catch 。。。 finally
上述内容概述:
异常处理
Error
Exception
Exception-- 编译期异常/受检异常(checked Exception) 必须处理
RuntimeException-- 运行时异常 /非受检异常(Unchecked Exception)
面试题:列举5个常见的运行时异常:
数组下标越界、空指针、类型转换、算数异输入类型匹配异常
处理方式:
1 默认处理(由jvm处理):在控制台输出异常信息 终止程序执行
2 try 。。。 catch。。。finally
获取异常信息的方式:Exception/子类 变量
两个方法:1.void printStacktrace();
2.String getMessage();
注意:try catch finally return(面试中的题)
final finally区别
2.throws(抛)
public static Date str2Date(String strDate) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//将获取的字符串的时间 转换为Date
Date d = sdf.parse(strDate);
return d;
}
try 和throws
throws抛出的异常的类型
throws可以抛出多种异常类型
声明抛出异常是Java中处理异常的第二种方式 :
如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这 种异常,
则此方法应显式地声明抛出异常,表明该方法将不对这些异常进行处理, 而由该方法的调用者负责处理。
在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可 以是方法中产生的异常类型,
也可以是它的父类。
在方法重写中 子类重写父类的方法时 不能抛出比父类更大范围的异常类型 子类只能抛出和父类相同的或者父类异常的子类异常及其 同级别的异常
四、手动抛出异常(throw)
public static void str2Date(String strDate) throws ParseException, FileNotFoundException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//将获取的字符串的时间 转换为Date
Date d = sdf.parse(strDate);
System.out.println(d);
//throw new NullPointerException("抛出异常对象 空指针异常");
throw new FileNotFoundException("文件不存在的编译期异常");
}
在抛出的时候 必须注意抛出的是异常对象 也就是必须new
1.注意:
1 手动抛出运行时异常 那么此时不需要在方法的声明上使用throws进行抛出
2 手动抛出编译期异常 此时必须将异常类型在方法的声明上使用throws 进行抛出给方法的调用者
2.throw 和throws的区别:
1 从使用的位置上:throws 方法的声明上 throw用在方法内部
2 抛出的异常类型:throws 抛出的是类型 throw 抛出的是对象
3 抛出的数量上:throws 可以抛出多个 throw 一次只能抛一个对象
3.throw的主要用途:
①异常类型的转换:
//将运行时异常转换为编译期异常
throw new Exception( new NullPointerException("抛出异常对象 空指针异常"));
//编译期异常转换为运行时异常
throw new RuntimeException(new FileNotFoundException("文件不存在的编译期异常"));
②自定义异常的抛出:
参考已知的运行时异常和编译期异常源文件写
运行异常:
编译异常:
例:
class MyException extends Exception {
static final long serialVersionUID = 13465653435L;
private int idnumber;
public MyException(String message, int id) {
super(message);
this.idnumber = id;
}
public int getId() {
return idnumber;
}
}
public class MyExpTest {
public void regist(int num) throws MyException {
if (num < 0)
throw new MyException("人数为负值,不合理", 3);
else
System.out.println("登记人数" + num);
}
public void manager() {
try {
regist(100);
} catch (MyException e) {
System.out.print("登记失败,出错种类" + e.getId());
}
System.out.print("本次登记操作结束");
}
public static void main(String args[]) {
MyExpTest t = new MyExpTest(); t.manager();
}
}
五、总结:异常处理5个关键字
世界上最遥远的距离,是我在if里你在else里,似乎一直相伴又永远分离;
世界上最痴心的等待,是我当case你是switch,或许永远都选不上自己;
世界上最真情的相依,是你在try我在catch。无论你发神马脾气,我都默 默承受,静静处理。到那时,再来期待我们的finally。
六、本节随堂练习链接:
来源:CSDN
作者:初学者150
链接:https://blog.csdn.net/weixin_45801537/article/details/103588966