异常

mac2024-02-24  78

异常

概述:异常就是Java程序在运行过程中出现的问题分类(以骑行为例): (1)错误,该问题不予处理,是严重问题,例如在骑行过程中车胎飞了 (2)异常,该问题可以处理,是一般问题,它又分为编译期异常和运行期异常 编译期异常:必须处理,不处理程序运行不了,例如在骑行之前发现车胎没气了 运行期异常:可处理也可不处理,例如在骑行过程中车胎没气了,我们可以选择处理,也可以选择不继续骑行 继承体系图: 编译期异常举例: package org.westos.demo2; import java.text.SimpleDateFormat; import java.util.Date; public class MyTest2 { public static void main(String[] args){ Date date = new Date(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); //直接调用parse方法会出现异常,这属于编译期异常 format.parse("2019-10-31"); System.out.println("后面的代码"); System.out.println("后面的代码"); System.out.println("后面的代码"); } }

编译期异常,程序无法正常运行

运行期异常举例:

public class MyTest2 { public static void main(String[] args) { int a=10; int b=0; System.out.println(a/b); } }

运行报错,自己没处理,交给虚拟机,打印异常类,异常信息和出现的位置,然后提出虚拟机,通过异常得知0不能作为除数

异常的处理方式 (1)交给虚拟机处理 在方法声明上用throws直接抛出,将异常抛给JVM,而虚拟机有一种默认的异常处理机制,处理完后将异常类名称,异常信息和出现异常的位置打印在控制台,并退出虚拟机 注意:如果抛出多个异常,这些异常必须是平级关系,不能有继承关系 package org.westos.demo2; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class MyTest2 { public static void main(String[] args) throws ParseException { Date date = new Date(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); //编译期异常 //直接调用parse方法会出现异常,直接抛出给虚拟机处理 //处理过后继续执行后面的代码 format.parse("2019-10-31"); System.out.println("后面的代码"); System.out.println("后面的代码"); System.out.println("后面的代码"); } }

(2)自己捕获异常并处理 通过try{}catch(){}finally{}捕获处理,其中try语句体写可能出现问题的语句,catch语句体写处理方式,finally是一个关键字,作用是必须执行该语句体,一般用于释放资源 注意:(1)try语句越少越好 (2)catch语句不能为空 (3)异常类型能明确尽量明确,不要用最大的异常去捕获 (4)异常类型平级关系无前后顺序,若是继承关系,父类必须在后面

package org.westos.demo2; import java.util.Scanner; public class MyTest2 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入第一个数字:"); int a=sc.nextInt(); System.out.println("请输入第二个数字:"); int b=sc.nextInt(); int[] arr={10,20,30}; try { //一旦遇到异常,就执行catch语句体 // try语句体里后面的代码不再执行 System.out.println(arr[10]); System.out.println(a/b); }catch (ArithmeticException e) { //实现自己对异常的处理 System.out.println("0为除数"); }catch (NullPointerException e) { //实现自己对异常的处理 System.out.println("空指针异常"); }catch (ArrayIndexOutOfBoundsException e) { //实现自己对异常的处理 System.out.println("数组角标越界异常"); }catch (Exception e) { //实现自己对异常的处理 System.out.println("其他异常"); }finally{ //无所有没有遇到异常都执行,一般用于释放资源 if(sc!=null){ //若sc为空,即没有被创建,就无需释放资源 sc.close(); } } //多个异常平级关系无前后顺序 //继承关系,父类必须写在后面 //这里其他异常类皆继承Exception异常类,所以Exception异常类写在最后面 //捕获异常并处理后,虚拟机不会退出,继续执行后面的代码 System.out.println("后面的代码"); System.out.println("后面的代码"); System.out.println("后面的代码"); } }

另外,捕获异常也通过自己的判断,然后throw关键字实现处理

package org.westos.demo2; import java.util.Scanner; public class MyTest2 { public static void main(String[] args){ Scanner sc = new Scanner(System.in); System.out.println("请输入第一个数字:"); int a=sc.nextInt(); System.out.println("请输入第二个数字:"); int b=sc.nextInt(); //自己判断是否有异常 if(b==0){ //有异常,通过throw关键字抛出异常对象处理 throw new ArithmeticException("除数为0"); }else{ //没有异常,执行语句 System.out.println(a/b); } } }

Throwable的常用方法: getMessage():获取异常信息,返回字符串 toString():获取异常类名和异常信息,返回字符串 printStackTrace():返回异常类型,异常信息和异常出现的位置

package org.westos.demo2; public class MyTest2 { public static void main(String[] args){ try{ System.out.println(1/0); }catch (ArithmeticException e){ //获取异常类名,异常信息和异常出现位置 e.printStackTrace(); System.out.println("---------------"); //获取异常信息 System.out.println(e.getMessage()); System.out.println("---------------"); //获取异常类名和异常信息 System.out.println(e.toString()); } } }

throws和throw的区别: throws用于方法声明上,可以抛出多种异常,但必须是平级关系;它抛出的是一种可能性,并不一定发生 throw用于方法内部,只能抛出一种异常;它只要抛出,代表该异常肯定发生了

final、finally和finalize的区别: final是一个权限修饰符,可以修饰类,方法,变量; 修饰类时,该类不可被继承 修饰方法时,该方法不可被重写 修饰变量时,该量是一个常量 finally用于捕获异常处理,无论有没有异常,该语句体都会执行,一般用于释放资源 finalize在垃圾回收时会调用

自定义异常

概述:在开发中,会遇到很多种异常,而有些异常是java没有提供的,这就需要我们自己编写一个异常类

编写异常类: 纳入异常体系,即继承Exception或者继承RuntimeException

举例(取款时余额不足异常):

package org.westos.demo2; //自己编写一个异常类并纳入异常体系 public class NoMoneyExcepton extends RuntimeException { public NoMoneyExcepton(String s){ super(s); } } import java.util.Scanner; public class MyTest2 { public static void main(String[] args){ //银行卡里金额 int num = 100; Scanner sc = new Scanner(System.in); System.out.println("请输入取款金额:"); int money = sc.nextInt(); if(num>=money){ System.out.println("取款成功"); }else{ //确定异常,通过异常对象抛出 throw new NoMoneyExcepton("余额不足"); } } }

注意事项:(1)子类重写父类方法,若父类没有抛出异常,子类也不可以抛出,若子类有异常,只能自己捕获处理 (2)若父类抛出异常,子类可以不抛出,也可以抛出父类异常的子集或者抛出一样的异常,但绝对不能比父类大

最新回复(0)