前言:
本文主要讨论Java中的异常,因为java是一种强类型语言,其中的异常处理和Python语言中的异常处理还是有些许区别!!!
目 录
一、异常
二、JVM 默认的异常处理
三、异常处理之 Try...catch...
四、Throwable 的成员方法
五、编译型异常和运行时异常
六、异常处理之Throws
七、自定义异常类
一、异常
异常:就是程序出现不正常的情况
案例如下:
package itheima2; public class ExceptionDemo { public static void main(String[] args) { // 调用方法 test(); } //定义方法 -- 注意:自定义方法必须有static修饰,但是自定义类中的方法不需要static 修饰 public static void test() { int[] arr = {1, 2, 3}; System.out.println(arr[3]); //超出数组索引范围, } /* 报错信息: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 at itheima2.ExceptionDemo.test(ExceptionDemo.java:14) at itheima2.ExceptionDemo.main(ExceptionDemo.java:7) */ }
二、JVM 默认的异常处理
// 如果程序出现了问题,我们没有解决。那么Java虚拟机JVM就会做默认处理 // 处理包括两个步骤: /* 1、将异常的名称、异常的原因和异常的位置输出在控制台 2、停止程序的运行 /*
三、异常处理之 Try...catch...
异常处理通常有两种方法:
Try ... catch.. 和 Throws
Try .. catch .. 格式及执行流程:
// try ...catch...异常处理 /* 格式: try { 可能出现异常部分的代码; } catch(异常类名 变量名) { 异常的处理代码; } 执行流程: 从try里面的代码开始执行,出现异常后会生成一个异常类对象,并且将这个异常类对象交给java运行时系统; java运行时系统会去catch中找匹配的异常类对象进行异常处理; 执行完异常处理的代码后程序会向下继续执行!!! */
案例:
package itheima2; // try ...catch...异常处理 /* 格式: try { 可能出现异常部分的代码; } catch(异常类名 变量名) { 异常的处理代码; } 执行流程: 从try里面的代码开始执行,出现异常后会生成一个异常类对象,并且将这个异常类对象交给java运行时系统; java运行时系统会去catch中找匹配的异常类对象进行异常处理; 执行完异常处理的代码后程序会向下继续执行!!! */ public class ExceptionDemo1 { public static void main(String[] args) { // TODO 方法调用 test(); } public static void test() { try { int[] arr = {1, 2, 3}; System.out.println(arr[3]); //超出数组索引范围, } catch (ArrayIndexOutOfBoundsException e) { System.out.println("索引错误,索引值超出数组的索引范围"); } } }
四、Throwable 的成员方法
Throwable 类是所有异常类的父类!如下图所示:
Throwable类成员方法及案例如下:
package itheima2; /* * Throwable 的成员方法, Throwable 类是 所有异常类的父类 * public String getMessage() 返回throwable的详细信息字符串 * public String toString() 返回可抛出的简短描述(原因) * public void printStackTrace() 将异常信息输出在控制台 * */ public class ExceptionDemo2 { public static void main(String[] args) { // TODO System.out.println("开始:"); test(); System.out.println("结束:"); } public static void test() { try { int[] arr = {1, 2, 3}; System.out.println(arr[3]); //超出数组索引范围, } catch (ArrayIndexOutOfBoundsException e) { // System.out.println("索引错误,索引值超出数组的索引范围"); //public String getMessage() 返回throwable的详细信息字符串 System.out.println(e.getMessage()); //public String toString() System.out.println(e.toString()); //public void printStackTrace() 将异常信息输出在控制台----最常用方法 e.printStackTrace(); //注意:调用printStackTrace方法时会直接打印出字符串,没有返回值;因此可以直接调用 /* * e.printStackTrace() 执行结果如下,可以看出和jvm默认的异常处理一样,但是程序不会终止,可以继续向下执行; * java.lang.ArrayIndexOutOfBoundsException: 3 at itheima2.ExceptionDemo2.test(ExceptionDemo2.java:22) at itheima2.ExceptionDemo2.main(ExceptionDemo2.java:15) */ } } }
五、编译型异常和运行时异常
异常通常分为编译时异常和运行时异常 //编译时异常通常都是 Exception类及其子类,需要显示处理,不然无法编译无法执行 //运行时异常通常都是 RuntimeException类,不需要显示处理
编译时异常可以理解为:在代码编写过程中代码飘红,出现错误导致代码无法执行;
运行时异常可以理解为:代码在编写过程中没有出现错误,但是执行结果显示错误。
具体案例如下:
package itheima2; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; // 编译时异常和运行时异常 public class ExceptionDemo3 { public static void main(String[] args) { // method(); method2(); } //自定义方法 public static void method() { int[] arr = {1, 2, 3}; System.out.println(arr[3]); //运行时错误: 编译通过,结果报错,可以直接在代码中修改 } public static void method2() { try { String ss = "2020-10-09"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date a = sdf.parse(ss); // 编译时错误:代码飘红-- System.out.println(a); } catch (ParseException e) { e.printStackTrace(); } } /* * sdf.parse() 报错信息:包括错误原因和错误位置 * java.lang.Error: Unresolved compilation problem: Unhandled exception type ParseException at itheima2.ExceptionDemo3.method2(ExceptionDemo3.java:25) at itheima2.ExceptionDemo3.main(ExceptionDemo3.java:12) */ }
六、异常处理之Throws
一般的异常使用try catch来处理,但是当遇到一些超出权限的异常时我们需要将异常抛出,比如说将异常抛给方法的调用者,由方法的调用者进行异常处理!!!
/* throws 异常处理格式如下: public void 方法名() throws 异常类名{
} 注意: 该格式放在方法()的后面 */
案例如下:
package itheima2; /* throws 异常处理方法 格式: throws 异常类名 注意: 该格式放在 方法()的后面。案例如下: */ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class ExceptionDemo4 { public static void main(String[] args) { // method(); //在方法调用的时候进行try catch 异常处理, 在方法编写的时候用throws 异常类名 ,将异常抛出 try { method2(); } catch(ParseException e) { e.printStackTrace(); } } //运行时异常 public static void method() { int[] arr = {1, 2, 3}; System.out.println(arr[3]); //运行时错误: 编译通过,结果报错,可以直接在代码中修改 } //编译时异常 public static void method2() throws ParseException{ String ss = "2020-10-09"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date a = sdf.parse(ss); // 编译时错误:代码飘红-- System.out.println(a); } }
七、自定义异常类
自定义异常类就是继承Exception类,并给出无参和带参构造方法!
案例如下:
自定义异常类:
package itheima2; // 自定义分数异常类,继承Exception类 public class ScoreException extends Exception{ //有参无参构造方法 public ScoreException(){} public ScoreException(String message) { super(message); } }
教师类:
package itheima2; //自定义教师类 public class Teacher { //成员方法 public void checkScore(int score) throws ScoreException { //利用throws来抛出异常,给方法调用者进行处理 //执行判断过程 if(score < 0 || score > 100) { //抛出异常信息,可以无参方法也可以是带参方法 // throw new ScoreException(); throw new ScoreException("给出的数值不在范围内"); } else { System.out.println("成绩正常!"); } } }
测试类:
package itheima2; import java.util.Scanner; public class TestDemo { public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner(System.in); System.out.println("请输入分数:"); int score = sc.nextInt(); //异常处理 try { Teacher tt = new Teacher(); tt.checkScore(score); } catch(ScoreException e) { e.printStackTrace(); } } } /* 执行结果如下: 请输入分数: 111 itheima2.ScoreException: 给出的数值不在范围内 at itheima2.Teacher.checkScore(Teacher.java:12) at itheima2.TestDemo.main(TestDemo.java:17) */