异常详细学习
Posted elvin-j-x
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异常详细学习相关的知识,希望对你有一定的参考价值。
异常的概念
异常,就是不正常的意思。在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响.在程序中的意思就是:
-
异常 :指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理。
注意:异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行.
异常体系
异常机制其实是帮助我们找到程序中的问题,异常的根类是java.lang.Throwable
,其下有两个子类:java.lang.Error
与 java.lang.Exception
,平常所说的异常指java.lang.Exception
。
Throwable体系:
-
Error:严重错误Error,无法通过处理的错误,只能事先避免,好比绝症。
-
Exception:表示异常,异常产生后程序员可以通过代码的方式纠正,使程序继续运行,是必须要处理的。好比感冒、阑尾炎。
Throwable中的常用方法:
1 public void printStackTrace()://打印异常的详细信息。 2 //包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用 printStackTrace 3 4 public String getMessage()://获取发生异常的原因。 5 //提示给用户的时候,就提示错误原因。 6 7 public String toString()://获取异常的类型和异常描述信息。 8 //出现异常,不要紧张,把异常的简单类名,拷贝到API中去查。
出现异常,不要紧张,把异常的简单类名,拷贝到API中去查。
异常分类
我们平常说的异常就是指Exception,因为这类异常一旦出现,我们就要对代码进行更正,修复程序。异常(Exception)的分类:根据在编译时期还是运行时期去检查异常?
编译时期异常:checked异常。在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)运行时期异常:runtime异常。在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错)。(如数学异常)
异常的产生过程解析
先运行下面的程序,程序会产生一个数组索引越界异常ArrayIndexOfBoundsException。我们通过图解来解析下异常产生的过程。
1 package _1异常和线程._2异常产生过程的解析; 2 3 /** 4 * @Author Admin 5 * @Classname DemoException 6 * @Package _1异常和线程._2异常产生过程的解析 7 * @GreatDate 2020/04/23 08:43:56 8 * @Description TODO 异常产生过程解析 9 */ 10 public class DemoException { 11 public static void main(String[] args) { 12 //创建int类型数组,并赋值 13 int[] arr = {1,2,3}; 14 int e = getElement(arr, 3); 15 System.out.println(e); 16 } 17 /* 18 定义一个方法,获取数组指定索引处的元素 19 参数: 20 int[] arr 21 int index 22 */ 23 private static int getElement(int[] arr,int index) { 24 int ele = arr[index]; 25 return ele; 26 } 27 }
异常的处理
Java异常处理的五个关键字:try、catch、finally、throw、throws
1、抛出异常throw
在编写程序时,我们必须要考虑程序出现问题的情况。比如,在定义方法时,方法需要接受参数。那么,当调用方法使用接受到的参数时,首先需要先对参数数据进行合法的判断,数据若不合法,就应该告诉调用者,传递合法的数据进来。这时需要使用抛出异常的方式来告诉调用者。
在java中,提供了一个throw关键字,它用来抛出一个指定的异常对象。那么,抛出一个异常具体如何操作呢?
-
创建一个异常对象。封装一些提示信息(信息可以自己编写)。
-
需要将这个异常对象告知给调用者。怎么告知呢?怎么将这个异常对象传递到调用者处呢?答:通过关键字throw就可以完成。throw 异常对象。throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。
throw关键字作用: 可以使用throw关键字在指定的方法中抛出指定的异常使用格式: throw new xxxException("异常产生的原因");注意: 1、throw关键字必须写在方法的内部 2、throw关键字后new的对象必须是Exception或者Exception的子类对象 3、throw关键字抛出指定的异常对象,我们必须处理这个异常对象; throw关键字后边创建的是RuntimeException或者是 RuntimeException的子类对象,我们可以不处理,默认交给JVM【虚拟机】(打印异常对象,中断程序); throw关键字后边创建的是编译异常(写代码的时候报错),我们就必须处理这个异常,要么try...catch(进行捕获处理),要么使用throws(继续讲问题声明出去)。
2、声明异常throws关键字
准备: Objects非空判断
使用其源吗进行演示throws关键字
还记得我们学习过一个类Objects吗,曾经提到过它由一些静态的实用方法组成,这些方法是null-save(空指针安全的)或null-tolerant(容忍空指针的),那么在它的源码中,对对象为null的值进行了抛出异常操作。 public static <T> T requireNonNull(T obj):查看指定引用对象不是null。 查看源码发现这里对为null的进行了抛出异常操作:
1 public static <T> T requireNonNull(T obj) { 2 if (obj == null) 3 throw new NullPointerException(); 4 return obj; 5 }
throws关键字使用
throws关键字:异常处理的第一种方式,交给别人处理作用: 当方法内部抛出异常对象的时候,那么我们就必须处理这个异常对象 可以使用throws关键字处理异常对象,会把异常对象声明抛出给方法的调用者处理(自己不处理,给别 人处理),最终会交给JVM【虚拟机】处理-->中断程序。
使用格式:
1 修饰符 返回值类型 方法名(参数列表) throws AAAException,BBBException...{ 2 throw new AAAException("产生异常的原因"); 3 throw new BBBException("产生异常的原因"); 4 ... 5 }
注意事项: 1、throws关键字必须写在方法的声明处【参数列表后,{}大括号前】 2、throws关键字后边声明异常必须是Exception或Exception的子类 3、方法的内部如果抛出多个异常对象,那么throws后边必须也声明多个异常, 如果抛出的多个异常对象有子父类关系,那么直接声明父类异常即可。 4、调用一个声明抛出异常的方法,我们就必须处理声明的异常, 要么继续使用throws声明抛出,交给方法的调用者处理,最终交给JVM【虚拟机】 要么捕获异常,即try...catch(自己处理异常)
实例:
1 package _1异常和线程._3异常的处理_关键字._2throws_关键字_异常处理的第一种方式$交给别人处理; 2 3 import java.io.FileNotFoundException; 4 import java.io.IOException; 5 6 /** 7 * @Author Admin 8 * @Classname DemoThrrows 9 * @Package _1异常和线程._3异常的处理_关键字._2throws_关键字 10 * @GreatDate 2020/04/23 13:49:00 11 * @Description TODO 演示声明异常throws关键字_异常处理的第一种方式$交给别人处理 12 */ 13 /* 14 throws关键字:异常处理的第一种方式,交给别人处理 15 作用: 16 当方法内部抛出异常对象的时候,那么我们就必须处理这个异常对象 17 可以使用throws关键字处理异常对象,会把异常对象声明抛出给方法的调用者处理(自己不处理,给别人处理) 18 最终会交给JVM【虚拟机】处理-->中断程序 19 使用格式: 20 修饰符 返回值类型 方法名(参数列表) throws AAAException,BBBException...{ 21 throw new AAAException("产生异常的原因"); 22 throw new BBBException("产生异常的原因"); 23 ... 24 } 25 26 注意事项: 27 1、throws关键字必须写在方法的声明处【参数列表后,{}大括号前】 28 2、throws关键字后边声明异常必须是Exception或Exception的子类 29 3、方法的内部如果抛出多个异常对象,那么throws后边必须也声明多个异常, 30 如果抛出的多个异常对象有子父类关系,那么直接声明父类异常即可。 31 4、调用一个声明抛出异常的方法,我们就必须处理声明的异常, 32 要么继续使用throws声明抛出,交给方法的调用者处理,最终交给JVM【虚拟机】 33 要么捕获异常,即try...catch(自己处理异常) 34 */ 35 public class DemoThrows { 36 /* 37 public static void main(String[] args) throws FileNotFoundException,IOException {} 38 */ 39 public static void main(String[] args) throws IOException { 40 readFile("d:a.tx"); 41 } 42 43 /* 44 定义一个方法,对传递的文件路径进行合法性判断 45 如果不是"c:a.txt",那么我们就抛出"文件找不到异常",告知方法的调用者 46 注意: 47 FileNotFoundException是编译异常,抛出了编译异常,就必须处理这个异常 48 可以使用throws继续声明FileNotFoundException这个异常对象,让方法的调用者处理。 49 50 原因: 51 FileNotFoundException extends IOException 该异常对象是子父类关系, 52 因此抛出的多个异常对象有子父类关系,那么直接声明父类异常即可。 53 */ 54 /* 55 private static void readFile(String filename) throws FileNotFoundException,IOException{} 56 */ 57 private static void readFile(String filename) throws IOException{ 58 if (!filename.equals("c:a.txt")) { 59 throw new FileNotFoundException("文件路径不是c:a.txt,文件找不到异常"); 60 } 61 /* 62 如果传递的路径,不是.txt结尾 63 那么我们就【抛出IO异常对象,告知方法的调用者"文件的后缀名不对" 64 */ 65 if (!filename.equals(".txt")) { 66 throw new IOException("文件的后缀名不对"); 67 } 68 System.out.println("路径没有问题,读取文件"); 69 } 70 }
3、捕获异常try…catch关键字
try...catch:异常处理的第二种处理方方式,自己处理异常语法格式:
1 try{ 2 //可能产生异常的代码 3 }catch(定义一个异常的变量,用来接收try中抛出的异常对象){ 4 /* 异常的处理逻辑,产生异常对象之后,怎么处理异常对象? 5 一般在工作中,会把异常的信息记录到一个日志中 6 */ 7 } 8 ... 9 catch(异常类名 变量名){ 10 }
注意事项:
1、try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象2、如果try中产生了异常,那么就会执行catch中的异常处理逻辑,执行完毕catch中的处理逻辑,继 续执行try...catch之后的代码语句。3、如果try中没有产生异常,那么就不会执行catch中异常的处理逻辑,执行网try中的代码,继续执行try...catch之后的代码语句。
Throwable类中定义了3方法查看异常信息:
1 public String getMessage()://获取异常的简短描述信息 2 public String toString()://获取异常的类型和异常详细描述信息【字符串】 3 public void printStackTrace()://JVM打印异常对象,默认此方法,打印的异常信息是最全面的(打印异常的跟踪栈信息并输出到控制台)。
实例:
1 package _1异常和线程._3异常的处理_关键字._3try_catch_关键字_异常处理的第二种方式$自己处理; 2 3 import javax.sound.midi.Soundbank; 4 import java.io.FileNotFoundException; 5 import java.io.IOException; 6 7 /** 8 * @Author Admin 9 * @Classname DemoTryCatch 10 * @Package _1异常和线程._3异常的处理_关键字._3try_catch_关键字_异常处理的第二种方式$自己处理 11 * @GreatDate 2020/04/23 19:22:17 12 * @Description TODO 演示捕获异常try_catch关键字_异常处理的第二种方式$自己处理异常 13 */ 14 /* 15 try...catch:异常处理的第二种处理方方式,自己处理异常 16 语法格式: 17 try{ 18 //可能产生异常的代码 19 }catch(定义一个异常的变量,用来接收try中抛出的异常对象){ 20 异常的处理逻辑,产生异常对象之后,怎么处理异常对象? 21 一般在工作中,会把异常的信息记录到一个日志中 22 } 23 ... 24 catch(异常类名 变量名){ 25 26 } 27 注意事项: 28 1、try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象 29 2、如果try中产生了异常,那么就会执行catch中的异常处理逻辑, 30 执行完毕catch中的处理逻辑,继续执行try...catch之后的代码语句。 31 3、如果try中没有产生异常,那么就不会执行catch中异常的处理逻辑, 32 执行网try中的代码,继续执行ry...catch之后的代码语句。 33 */ 34 public class DemoTryCatch { 35 public static void main(String[] args) { 36 try { 37 //可能产生异常的代码 38 readFile("c:a.txt"); 39 } catch (IOException e) { 40 //try中抛出什么异常对象,cotch就定义什么异常变量,用来接收这个异常对象 41 //异常的处理逻辑,产生异常对象之后,怎么处理异常对象? 42 // System.out.println("catch -文件路径不是c:a.txt,文件找不到异常"); 43 // System.out.println("catch -传递的文件后缀不是.txt"); 44 45 /* 46 Throwable类中定义了3方法查看异常信息: 47 public String getMessage() :获取异常的简短描述信息 48 public String toString() :获取异常的类型和异常详细描述信息【字符串】 49 public void printStackTrace() : 50 JVM打印异常对象,默认此方法,打印的异常信息是最全面的 51 (打印异常的跟踪栈信息并输出到控制台)。 52 */ 53 System.out.println(e.getMessage());//文件的后缀名不对 54 //System.out.println(e.toString()); 55 //重写Object类的toString java.io.IOException:文件的后缀名不对 56 System.out.println(e); 57 //该代码语句等同于System.out.println(e.toString()); 58 e.printStackTrace(); 59 /* 60 java.io.IOException: 文件的后缀名不对 61 at _1异常和线程._3异常的处理_关键字._3try_catch_关键字_异常处理的第二种 方式$自己处理.DemoTryCatch.readFile(DemoTryCatch.java:70) 62 at _1异常和线程._3异常的处理_关键字._3try_catch_关键字_异常处理的第二种 方式$自己处理.DemoTryCatch.main(DemoTryCatch.java:38) 63 64 */ 65 } 66 System.out.println("后续的代码"); 67 } 68 private static void readFile(String filename) throws IOException { 69 if (!filename.equals("c:a.txt")) { 70 throw new FileNotFoundException("文件路径不是c:a.txt,文件找不到异常"); 71 } 72 /* 73 如果传递的路径,不是.txt结尾 74 那么我们就【抛出IO异常对象,告知方法的调用者"文件的后缀名不对" 75 */ 76 if (!filename.endsWith(".txt")) { 77 throw new IOException("文件的后缀名不对"); 78 } 79 System.out.println("路径没有问题,读取文件"); 80 } 81 }
finally 代码块
finally:有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行不到。而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的。
注意:1、finally不能单独使用,必须和try一起使用2、finally一般用于资源释放(资源回收),无论线程是否会出现异常,最后都要资源释放 (多是用于IO流方面)
1 语法格式: 2 try{ 3 //可能产生异常的代码 4 }catch(定义一个异常的变量,用来接收try中抛出的异常对象){ 5 /* 异常的处理逻辑,产生异常对象之后,怎么处理异常对象? 6 一般在工作中,会把异常的信息记录到一个日志中 7 */ 8 } 9 ... 10 catch(异常类名 变量名){ 11 12 }finally{ 13 //无论是否出现异常都会执行 14 }
异常,就是不正常的意思。在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响.在程序中的意思就是:
-
异常 :指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理。
注意:异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行.
异常体系
异常机制其实是帮助我们找到程序中的问题,异常的根类是java.lang.Throwable
,其下有两个子类:java.lang.Error
与 java.lang.Exception
,平常所说的异常指java.lang.Exception
。