异常:Exception
一、什么是异常
我们的程序在运行过程中产生的一些问题,这些问题有的是编码错误,有的是用户不正当操作引起的,有的是外部物理设备引起的。
二、异常的继承结构
Throwable:可抛出的
-->EXception:异常
一般都是程序编写问题或用户不正当操作引起的,
通过程序代码来进行解决
------>编译期异常(检查异常)
程序在编译期间,由编译器检查出来的异常,必须要处理,否则编译不能通过
------>运行时异常(非检查异常)
所有的运行时异常会继承自RuntimeException;
运行时异常在编译期间检测不到,但是在运行期间有可能会报异常,可以不处理也可以处理
如:ArratyIndexOutOfBoundException
NUllPointException
-->Error:错误
一般是由物理设备引起的,无法通过代码来解决,一般我们不要处理
StackoverFlowError:栈溢出错误
OutOfMemoryError:堆内存溢出
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Scanner;
-
- /*
- * 检查异常处理方式:抛出
- */
- public class TestException01 {
- /**
- * 调用m1()方法,因为m1()方法也没有处理异常,
- * 所以main()方法看到的就是有异常的m1()方法
- * main()方法继续向上抛出异常,最终抛给了jvm虚拟机
- * jvm打印出异常的堆栈信息
- *
- * 客人:服务员将炒糊的菜端给了客人,客人看到的菜就是炒糊的菜
- * @param args
- * @throws Exception
- */
-
- public static void main(String[] args) throws Exception {
- //看到两个异常的m01()方法
- //客人看到的菜是既炒糊了,又没盐的
-
- //看到的就是只有一个父异常的m1()方法
- //客人也只知道才没炒好,不指定具体哪里没炒好
- //m01();
- m02();
- }
- /**
- * 调用m0方法,因为m0中抛出异常,所以调用就是有异常的m0()方法
- *
- * m1()可以选择继续向上抛出,谁来调用m1()这个方法就抛给谁
- * 服务员:去取厨师炒的菜,看到就是炒糊的菜
- * @throws Exception
- */
- public static void m1() throws Exception {
- //看到两个异常的m01()方法
- //服务员看到的菜是既炒糊了,又没盐的
- //m01();
-
- //服务员只知道菜没炒好,但不知道具体哪没炒好
- /*
- * m1()只会看到父异常的Exception,不知道哪个没炒好
- */
- m02();
- }
-
- /*
- * 让用户控制台输入一个指定格式字符串
- * 然后将这个字符串解析为日期对象
- *
- * 异常:菜炒糊了
- * :没放盐
- * :油多了
- * 抛出:不处理,向上抛出不管,
- * 谁来调用这个方法,谁处理
- * @throws:ParseException
- * @throws:FileNotFoundException
- */
-
-
- public static void m01() throws ParseException, FileNotFoundException {
- System.out.println("请输入日期(yyyy-MM-dd)");
-
- String dateStr=new Scanner(System.in).nextLine();
- SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
- Date date =sdf.parse(dateStr);
- System.out.println("date="+date);
-
- //尝试去连接一个磁盘文件
- FileInputStream in=new FileInputStream ("D:/a.text");
- }
-
- /*
- * 让用户控制台输入一个指定格式字符串
- * 然后将这个字符串解析为日期对象
- *
- * 异常:菜炒糊了
- * :没放盐
- * :油多了
- *
- *总问题:没炒好
- * 抛出:不处理,向上抛出不管,
- * 谁来调用这个方法,谁处理
- * 抛出的是一个父类型的异常
- * @throws:ParseException
- * @throws:FileNotFoundException
- */
-
-
- public static void m02() throws Exception {
- System.out.println("请输入日期(yyyy-MM-dd)");
-
- String dateStr=new Scanner(System.in).nextLine();
- SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
- Date date =sdf.parse(dateStr);
- System.out.println("date="+date);
-
- //尝试去连接一个磁盘文件
- FileInputStream in=new FileInputStream ("D:/a.text");
- }
- }
2、捕获
如果异常需要自己处理,也可以在方法内部通过try~catch 来对异常进行捕获并处理,那么方法调用者就不需要再去
处理异常了
语法:
try{
//有检查异常的代码块
}catch(XXException e){
//捕获异常并处理
}catch(XXException e){
//捕获异常并处理
}。。。
finally{
//最终执行代码块。可以没有
}
注意:
1》try中代码块出现了异常,那么跟在这一行的后面的try中代码都不执行
2》finally为最终执行代码块,是必须要执行的,即使try或者catch中有return,也会先去执行finally中代码,再回去执行return
3》如果有多个检查异常,catch可以有多个这些异常之间如果有父子关系,那么子类型必须写在父类型的上面,否则捕获不到或者通过一个catch类型捕获这多个异常的父类型异常
4》如果有必须要执行的代码块,可以单独使用try和finally
5》运行时异常通常不需要处理,
如果要处理,也可以按照检查异常一样去处理
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Scanner;
-
- /**
- * 异常处理方式:捕获
- *
- */
- public class TestException02 {
- public static void main(String[] args) {
- //客人看到的就是没有问题的菜
- m03();
- }
-
- /*
- * 因为厨师自己处理了炒糊的菜
- * 服务员考到的就是没有问题的菜
- *
- *
- *
- * 因为m0()方法自己捕获了异常
- * 所以m1()在调用m0()时不需要在处理异常了
- */
- public static void m1() {
- m03();
- }
-
- /**
- * 让用户控制台输入一个指定格式字符串
- * 然后将这个字符串解析为日期对象
- *
- * 异常:菜炒糊了
- * :没放盐
- * :油多了
- * 捕获:厨师自己处理炒糊的菜(摘出来,重新炒)
- * @throws:ParseException
- * @throws:FileNotFoundException
- */
-
-
- public static void m0() {
- System.out.println("请输入日期(yyyy-MM-dd)");
-
- String dateStr = new Scanner(System.in).nextLine();
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
- Date date;
- try {
- // 尝试去运行这块代码
- date = sdf.parse(dateStr);
- //try中代码出现异常,那么跟在后面的代码都不执行
- System.out.println("date=" + date);
- return;
- } catch (ParseException e) {
- // 只有Try中代码出现了异常
- // 才会catch中的代码
- System.out.println("==处理炒糊的菜==");
- //参数e代表捕获到的异常
- System.out.println("e:"+e);
- //获取异常信息
- String message =e.getMessage();
- System.out.println("message:"+message);
-
- //与jvm一样,打印输出异常的堆栈信息
- //e.printStackTrace();
- return;
- }finally {
- //最终执行代码块,无论try中代码有无异常
- //或try和catch中有无return,都会来执行的代码
- System.err.println("====最终执行代码块====");
- }
- }
- /**
- * 让用户控制台输入一个指定格式字符串
- * 然后将这个字符串解析为日期对象
- *
- * 异常:菜炒糊了
- * :没放盐
- * :油多了
- * 捕获:厨师自己处理炒糊的菜(摘出来,重新炒)
- * @throws:ParseException
- * @throws:FileNotFoundException
- */
-
-
- public static void m01() {
- System.out.println("请输入日期(yyyy-MM-dd)");
-
- String dateStr = new Scanner(System.in).nextLine();
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
- Date date;
- try {
- // 尝试去运行这块代码
- date = sdf.parse(dateStr);
- //从磁盘上读取数据,可能会发生读取异常
- FileInputStream in=new FileInputStream ("D:/a.text");
- in.read();
- //try中代码出现异常,那么跟在后面的代码都不执行
- System.out.println("date=" + date);
-
- return;
- } catch (ParseException e) {
- // 只有Try中代码出现了异常
- // 才会catch中的代码
- System.out.println("==日期解析异常==");
- //参数e代表捕获到的异常
- System.out.println("e:"+e);
- //获取异常信息
- String message =e.getMessage();
- System.out.println("message:"+message);
-
- //与jvm一样,打印输出异常的堆栈信息
- //e.printStackTrace();
- return;
- } catch (FileNotFoundException e) {
- //只有try中代码发生了文件未找到异常才能进入到这里执行
- //因为FileNotFoundException是IOException的子类型
- //要放在父类型的上面
- System.out.println("==文件未找到异常==");
- } catch (IOException e) {
- System.out.println("===文件读取异常====");
- e.printStackTrace();
- }finally {
- // e.printStackTrace();
- //最终执行代码块,无论try中代码有无异常
- //或try和catch中有无return,都会来执行的代码
- System.err.println("====最终执行代码块====");
- }
- }
-
-
- /**
- * 让用户控制台输入一个指定格式字符串
- * 然后将这个字符串解析为日期对象
- *
- * 异常:菜炒糊了
- * :没放盐
- * :油多了
- * 捕获:厨师自己处理炒糊的菜(摘出来,重新炒)
- * @throws:ParseException
- * @throws:FileNotFoundException
- */
-
-
- public static void m02() {
- System.out.println("请输入日期(yyyy-MM-dd)");
-
- String dateStr = new Scanner(System.in).nextLine();
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
- Date date;
- try {
- // 尝试去运行这块代码
- date = sdf.parse(dateStr);
- //从磁盘上读取数据,可能会发生读取异常
- FileInputStream in=new FileInputStream ("D:/a.text");
- in.read();
- //try中代码出现异常,那么跟在后面的代码都不执行
- System.out.println("date=" + date);
-
- return;
- } catch (Exception e) {
- System.out.println("==发生了异常,菜没炒好==");
- if(e instanceof ParseException) {
- System.out.println("日期");
- }else if(e instanceof FileNotFoundException) {
- System.out.println("文件没找到");
- }else if(e instanceof IOException) {
- System.out.println("读取异常");
- }else {
- System.out.println("其他异常");
- }
- return;
- } finally {
- // e.printStackTrace();
- //最终执行代码块,无论try中代码有无异常
- //或try和catch中有无return,都会来执行的代码
- System.err.println("====最终执行代码块====");
- }
-
-
-
- }
-
- /**
- * 运行时候异常:通常不需要处理
- * 如果想处理,也可以按照检查异常去处理
- *
- * 如果有必要执行的代码
- * try和finally可以单独使用
- */
- public static void m03() {
- String arr[]= {"aa","bb","cc"};
- // try {
- // System.out.println(arr[5]);
- // }catch(ArrayIndexOutOfBoundsException e) {
- // System.out.println("数组下标越界异常");
- // }
-
- try {
- System.out.println(arr[1]);
- }finally {
- System.out.println("123456789");
- }
- }
- }
-
-
-