异常-Exception
一,异常的介绍
1,异常的引入 ,什么是异常
运行下面的代码,看看有什么问题-> 引出异常和异常处理机制
public class Exception01 {
public static void main(String[] args) {
int num1 = 10;
int num2 = 0;
int res = num1 / num2;
System.out.println(res);
System.out.println("程序正常运行");
}
}
//1. num1 / num2 => 10 / 0
//2. 当执行到 num1 / num2 因为 num2 = 0, 程序就会出现(抛出)异常 ArithmeticException
//3. 当抛出异常后,程序就退出,崩溃了 , 下面的代码就不在执行
//4. 大家想想这样的程序好吗? 不好,不应该出现了一个不算致命的问题,就导致整个系统崩溃
//5. java 设计者,提供了一个叫 异常处理机制来解决该问题
int res = num1 / num2;
//如果程序员,认为一段代码可能出现异常/问题,可以使用 try-catch 异常处理机制来解决 //从而保证程序的健壮性
//将该代码块->选中->快捷键 ctrl + alt + t -> 选中 try-catch
//6. 如果进行异常处理,那么即使出现了异常,程序可以继续执行
public class Exception01 { public static void main(String[] args) { int num1 = 10; int num2 = 0; try { int res = num1 / num2; System.out.println(res); } catch (Exception e) { System.out.println("程序错误的原因" + e.getMessage()); } System.out.println("程序正常运行"); } }
2.异常的介绍
在java语言中,将程序执行中发生的不正常情况称之为”异常“ ,(开发过程中的语法错误和逻辑错误不是异常)
在执行过程中所发生的异常时间分为两大类
1. Error(错误):java虚拟机无法解决的严重问题,如:jvm系统内部错误,资源耗尽等严重情况,比如:StackOverFlowError【栈溢出】OOM(out of memory),Error 最严重,程序可能会崩溃。
2.Exception : 其原因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理,例如空指针访问,试图读取不存在的文件,网络连接中断等,Exception 分为两大类:运行时异常和编译时异常。
3. 异常体系图

异常体系图小结:
1. 异常分为两大类,运行时异常和编译时异常
2.运行时异常,编译器检查不出来,一般是指编程时的逻辑错误,时程序员应该避免其出现的异常。java.lang.RuntimeException类及它的子类都是运行时异常
3.对于运行时异常,可以不做处理,因为这类异常很普遍,若是处理可能会对程序的可读性和运行效率产生影响
4.运行时异常(RuntimeException)
NullPointerException 空指针异常 ,对象为null时,尝试调用属性跟方法,就会抛出异常
ArrayIndexOutOfBoundsException 数组索引越界异常,当尝试使用一个大于等于数组长度的索引或者负数索引时 抛出该异常
StringIndexOutOfBoundsException 字符串索引越界异常, 当尝试使用一个大于等于数组长度的索引或者负数索引时 抛出该异常
NumberFormatException 数字格式化异常 将一个非纯数字序列的字符串尝试转换成整数时 抛出该异常 *
InputMismatchException 输入不匹配异常 Scanner 当输入的类型和接收类型不匹配时 抛出该异常
ClassCastException 类型转换异常* 将对象尝试转换成不是同一个类型时 抛出该异常
常见的运行时异常举例

public class NullPointerException_ { public static void main(String[] args) { String name = null; System.out.println(name.length()); //NullPointerException } }

public class Exception01 { public static void main(String[] args) { int num1 = 10; int num2 = 0; int res = num1 / num2; System.out.println(res); //ArithmeticException } }

NumberFormatException
public class NumberFormatException_ { public static void main(String[] args) { String name = "好好学java"; int i = Integer.parseInt(name); System.out.println(i); //NumberFormatException } }

public class ArrayIndexOutOfBoundsException_ { public static void main(String[] args) { int[] arr = {12,2,3}; for (int i = 0; i <= arr.length; i++) {//不能等于arr.length System.out.println(arr[i]); //ArrayIndexOutOfBoundsException } } }

public class ClassCastException_ { public static void main(String[] args) { A a = new B(); //向上转型 B b = (B)a; //向下转型 C c = (C)a ; //ClassCastException 先向上转型,然后在向下转型 } } class A{} class B extends A{} class C extends A{}
5. 编译时异常
1. 介绍
编译异常是指在编译期间,就必须处理的异常,否则代码不能通过编译
2.常见的编译异常

二,异常的处理
异常中的三个方法
getMessage() 获取异常信息,返回字符串。 注意: 有的异常的异常信息为null
toString() 获取异常类名和异常信息,返回字符串。
printStackTrace( 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
一般使用这个方法打印异常, 能够清晰直观的看到异常是哪一行代码导致的
1. 基本介绍
异常处理就是当异常发生时,对异常的处理方式
2. 异常处理的方式

3. 示意图


4. try - cathch 的异常处理

5. try - cathch 的注意事项
1)ctrl + atl + t 快捷键
2)如果发生异常了,则异常发生后面的代码不会执行,直接进入到catch块
3)如果异常没有发生,则顺修执行try的代码块,不会进入到catch
4)如果希望不管是否发生异常,都会执行某段代码(比如关闭连接,释放资源等)则使用如下代码
try{
//可疑代码
}catch(异常){
//.....
}finally{
//释放资源等等
}
public class TryCatchDetail02 { public static void main(String[] args) { //1.如果 try 代码块有可能有多个异常 //2.可以使用多个 catch 分别捕获不同的异常,相应处理 //3.要求子类异常写在前面,父类异常写在后面 try { Person person = new Person(); //person = null; System.out.println(person.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()); } finally { } } } class Person { private String name = "jack"; public String getName() { return name; } }
6)可以进行try - finally 配合使用,这种用法相当于没有捕获异常,因此程序会直接崩掉/退出。应用场景,就是执行一段代码,不管是否发生异常,都必须执行某个业务逻辑
try{
//异常代码
}finally{
//总是执行
}
6. try-catch-finally 执行顺序小结

小练习
public class TryCatchExercise04 { public static void main(String[] args) { // 如果用户输入的不是一个整数,就提示他反复输入,直到输入一个整数为止 Scanner scanner = new Scanner(System.in); String key = ""; int num = 0; while (true){ System.out.println("请输入一个整数"); key = scanner.next(); try { num = Integer.parseInt(key); break; } catch (NumberFormatException e) { System.out.println("你输入的不是一个整数"); } } System.out.println("你输入的值时=" + num); } }
三,throws 异常处理
1.基本介绍
1)如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,则由该方法的调用这负责处理。
2)在方法声明中用throws语句可以声明抛出异常的列表,thorws后面的异常类型可以是方法中产生的异常类型,也就是他的父类。
2.注意事项和使用细节
1)对于编译异常,程序中必须处理,比如try-chtch 或者 thorws
2) 对于运行时异常,程序中如果没有处理,默认就是throws的方式处理
3)子类重写父类的方法时,对于抛出异常的规定:子类重写的方法,所抛出的异常类型要么是和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型
4)在throws过程中,如果有方法try-catch ,就相当于处理异常,就可以不必throws
一个方法调用另一个方法。如果被调用的方法中抛出了编译时异常,则调用者也要抛出编译时异常。如果被调用者抛出运行时异常,则调用者不用抛出异常,因为默认会抛出thorws异常。
四,自定义异常
1. 基本概念
当程序中出现了某些“错误”,但该错误信息并没有在Throwable子类中描述处理,这个时候可以自己设计异常类,用于描述需错误信息。
2.自定义异常步骤

3 . 自定义异常的应用实例
当我们接收Person对象年龄时,要求范围在18-120 之间,否则抛出一个自定义异常(需求:继承RuntimeException)
public class CustomException { public static void main(String[] args) { int age = 80; //要求范围在 18 – 120 之间,否则抛出一个自定义异常 if(!(age >= 18 && age <= 120)) { //这里我们可以通过构造器,设置信息 throw new AgeException("年龄需要在 18~ 120 之间"); } System.out.println("你的年龄范围正确."); } } // 一般情况下,我们自定义异常是继承 RuntimeException //2. 即把自定义异常做成 运行时异常,好处时,我们可以使用默认的处理机制 class AgeException extends RuntimeException{ public AgeException(String message) { //构造器 super(message); } }
五,throw 和 throws 的区别

throws 是写在方法的定义上面 在参数列表之后 通过抛出多个异常来抛出给下一个调用者
throw是 手动抛出一个异常对象 直接使程序报错终止

浙公网安备 33010602011771号