从这节开始,进入对I/O流的系统学习,I/O流在往后大数据的学习道路上尤为重要!!!极为重要,必须要提起重视,它与集合,多线程,网络编程,可以说在往后学习或者是工作上,起到一个基石的作用,没了地基,房屋就算盖起来,风一吹就倒。
好了,废话不多说,进入正题:在学习I/O流之前,我们先掌握什么是异常和File
1、先看看异常的分类:
图1 异常的分类
从上图我们不难看出来,异常主要分为三大类:Error Exception RuntimeException
有朋友就要问了,上来就给我搞这些什么异常,还分类,不好理解啊!!别急,我来白话文说说:
什么是异常?
就是程序出现了不正常的情况。
还不清楚?继续举例:
比如说,今天天气很好,我要去市中心逛街,骑着自行车,去购物。但是呢?我遇到了一些问题:
问题1:去的路上我发生了车祸,我去不了了,这属于严重的问题。
问题2:我推着自行车,发现气儿没了,把气充起来,这属于出发前就应该检查的问题。
问题3:我骑着自行车在路上骑着,路两边是小石子路,但是我就是往上面骑车,结果我爆胎了,这属于运行时候出现的问题
相对应着:
程序的异常:Throwable
严重问题:Error 我们不处理,这种问题一般都是很严重的问题,比如说内存溢出
异常:Exception
又分为:
编译时期的异常:不是RuntimeException的异常,必须进行处理的,因为你不进行处理,编译就不会通过。
运行时期的异常:RuntimeException 这种问题我们也不处理,因为是程序员自身的问题,而且这个问题的出现肯定是我们的代码不够严谨,必须要进行修正代码的。
说了那么多,应该对什么是异常有了大概的了解了吧,接下来看操作!!嘿嘿
2、如果程序出现了问题,我们没有做任何处理,最终JVM(Java虚拟机)会做出默认的处理(把异常的名称,原因以及出现的问题位置等信息输出在控制台,同时会结束程序)如下代码:
1 package com.wyh.IO流day1; 2 3 4 /** 5 6 * 创建时间:2019年11月28日 下午8:53:26 7 8 * 项目名称:practise09_IO流(2) 9 10 * @author WYH 11 12 * @version 1.0 13 14 * @since JDK 1.8.0 15 16 * 文件名称:ExceptionDemo1.java 17 18 * 类说明: 19 * try{ 20 * 21 * }catch(){ 22 * 23 * }finally{ 24 * 25 * } 26 */ 27 28 public class ExceptionDemo1 { 29 public static void main(String[] args) { 30 int i = 10; 31 int j = 0; 32 // try { 33 System.out.println(i/j); 34 // } catch (Exception e) { 35 // System.out.println("除数不能为0"); 36 // } 37 // 38 System.out.println("over"); 39 40 } 41 42 }
如何处理异常:
注意:
1、try里面的代码越少越好,因为Java虚拟机开辟的内存资源就会越少
2、一旦try里面出了问题,就会在这里把问题抛出去,然后和catch里面的问题进行匹配。
3、一旦有匹配的,就执行catch里面的处理。然后结束了try...catch...继续执行后面的语句
JDK7出现了一个新的异常处理方案:
代码展示:
1 package com.wyh.IO流day1; 2 3 4 /** 5 6 * 创建时间:2019年11月28日 下午8:53:26 7 8 * 项目名称:practise09_IO流(2) 9 10 * @author WYH 11 12 * @version 1.0 13 14 * @since JDK 1.8.0 15 16 * 文件名称:ExceptionDemo1.java 17 18 * 类说明: 19 * JDK7版本新出现的异常处理方式 20 * try{ 21 * ... 22 * }catch(异常类名1 | 异常类名2 | 异常类名3.. 异常名){ 23 * .... 24 * } 25 * 26 */ 27 28 public class ExceptionDemo2 { 29 public static void main(String[] args) { 30 int i = 10; 31 int j = 0; 32 int[] arr =new int[3]; 33 try { 34 System.out.println(i/j); 35 System.out.println(arr[3]); 36 } catch (ArithmeticException | ArrayIndexOutOfBoundsException e) { 37 System.out.println("出现异常"); 38 } 39 40 System.out.println("over"); 41 42 } 43 44 }
3、接下来学习一些Throwable中的方法:
getMessage() 获取异常信息,返回字符串
toString() 获取异常类名和异常信息,返回字符串
printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void
printStackTrace() 通常用该方法将异常内容保存在日志文件中,以便查阅。
1 package com.wyh.IO流day1; 2 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.Date; 6 7 8 /** 9 10 * 创建时间:2019年11月28日 下午8:53:26 11 12 * 项目名称:practise09_IO流(2) 13 14 * @author WYH 15 16 * @version 1.0 17 18 * @since JDK 1.8.0 19 20 * 文件名称:ExceptionDemo1.java 21 22 * 类说明: 23 * try{ 24 * 25 * }catch(){ 26 * 27 * } 28 * 的三种方法 29 * 30 */ 31 32 public class ExceptionDemo4 { 33 public static void main(String[] args) { 34 35 //编译时异常 36 String s = "2019-11-28"; 37 SimpleDateFormat ds = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); 38 try { 39 Date d = ds.parse(s); 40 System.out.println(d); 41 } catch (ParseException e) { 42 // e.printStackTrace(); 43 // System.out.println("解析日期出现了错误"); 44 45 46 //方法一:getMessage() 47 // System.out.println(e.getMessage());//Unparseable date: "2019-11-28" 48 49 //方法二:toString() 50 // System.out.println(e.toString());//java.text.ParseException: Unparseable date: "2019-11-28" 51 52 //方法三:e.printStackTrace() 而我们经常使用的是这个 53 /*java.text.ParseException: Unparseable date: "2019-11-28" 54 at java.text.DateFormat.parse(DateFormat.java:366) 55 at com.wyh.IO流day1.ExceptionDemo4.main(ExceptionDemo4.java:39)*/ 56 e.printStackTrace(); 57 58 59 } 60 } 61 62 }
小结:
4、throw
在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。
举例:
1 package com.wyh.IO流day1; 2 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.Date; 6 7 /** 8 * 9 * 创建时间:2019年11月28日 下午8:53:26 10 * 11 * 项目名称:practise09_IO流(2) 12 * 13 * @author WYH 14 * 15 * @version 1.0 16 * 17 * @since JDK 1.8.0 18 * 19 * 文件名称:ExceptionDemo1.java 20 * 21 * 类说明: throw 22 * 23 */ 24 25 public class ExceptionDemo6 { 26 public static void main(String[] args) { 27 System.out.println("我热爱大数据"); 28 29 //在main方法里尽量不使用抛出,因为如果出错就无法走下去。 30 try { 31 method1(); 32 } catch (ParseException e) { 33 // TODO Auto-generated catch block 34 e.printStackTrace(); 35 } 36 37 try {//为了保证程序正常进行运行 38 method2();//运行时期的异常调用时不做处理,如果出错依旧停止程序 39 } catch (Exception e) { 40 e.printStackTrace(); 41 } 42 43 44 System.out.println("所以我现在是大牛"); 45 46 } 47 48 49 50 //运行时期的异常在方法调用的时候可以不去处理 51 private static void method2() throws ArithmeticException{ 52 int i = 10; 53 int j = 0; 54 System.out.println(i/j); 55 56 } 57 58 59 60 //编译时期的异常方法我们必须进行处理,抛出 61 private static void method1() throws ParseException { 62 // 编译时异常 63 String s = "2019-11-28"; 64 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); 65 Date d = sdf.parse(s); 66 System.out.println(d); 67 68 } 69 }
下面有一道这样的面试题:
(怎么找异常??跟进鼠标看方法是继承了什么异常类,看父类)
5、finally:被finally控制的语句一定会执行
1 package com.wyh.IO流day1; 2 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.Date; 6 7 /** 8 * 9 * 创建时间:2019年11月28日 下午8:53:26 10 * 11 * 项目名称:practise09_IO流(2) 12 * 13 * @author WYH 14 * 15 * @version 1.0 16 * 17 * @since JDK 1.8.0 18 * 19 * 文件名称:ExceptionDemo1.java 20 * 21 * 类说明: finally 22 * 注意:如果程序在执行到finally之前退出了,就不会执行 23 * 24 */ 25 26 public class ExceptionDemo7 { 27 public static void main(String[] args) { 28 String s = "2019-11-29"; 29 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); 30 31 Date d = null; 32 33 try { 34 sdf.parse(s); 35 } catch (ParseException e) { 36 e.printStackTrace(); 37 System.exit(0); 38 }finally{ 39 System.out.println("这条语句时可以被执行的"); 40 } 41 42 System.out.println(d); 43 44 45 } 46 }
那么就有这样的面试题:
6、自定义异常:
(1)自定义类并继承Exception父类:
1 package com.wyh.自定义异常; 2 3 /** 4 5 * 创建时间:2019年11月29日 下午8:42:32 6 7 * 项目名称:practise09_IO流(2) 8 9 * @author WYH 10 11 * @version 1.0 12 13 * @since JDK 1.8.0 14 15 * 文件名称:MyException.java 16 17 * 类说明: 18 * 两种方式实现自定义异常(这里使用继承Exception) 19 20 */ 21 22 public class MyException extends Exception{ 23 //无参构造 24 public MyException(){ 25 26 } 27 28 //有参构造,传递消息 29 public MyException(String s){ 30 super(s); 31 } 32 }
(2)自定义另一个类,写方法,方法中抛出我们刚刚自定义的类:
1 package com.wyh.自定义异常; 2 3 /** 4 5 * 创建时间:2019年11月29日 下午8:55:18 6 7 * 项目名称:practise09_IO流(2) 8 9 * @author WYH 10 11 * @version 1.0 12 13 * @since JDK 1.8.0 14 15 * 文件名称:MyTeacher.java 16 17 * 类说明: 18 * 定义新类,定义新的方法,使用自定义的异常 19 20 */ 21 22 public class MyTeacher { 23 24 public void check(int i) throws MyException{ 25 if(i>100 || i<0){ 26 throw new MyException("分数必须在0到100之间"); 27 }else{ 28 System.out.println("分数合理"); 29 } 30 } 31 32 33 34 }
(3)测试类:
1 package com.wyh.自定义异常; 2 3 import java.util.Scanner; 4 5 /** 6 * 7 * 创建时间:2019年11月29日 下午8:58:32 8 * 9 * 项目名称:practise09_IO流(2) 10 * 11 * @author WYH 12 * 13 * @version 1.0 14 * 15 * @since JDK 1.8.0 16 * 17 * 文件名称:ExceptionDemo.java 18 * 19 * 类说明: 测试我们的自定义异常 20 */ 21 22 public class ExceptionDemo { 23 public static void main(String[] args) { 24 Scanner sc = new Scanner(System.in); 25 MyTeacher t = new MyTeacher(); 26 while (true) { 27 System.out.println("请输入你的分数:"); 28 int i = sc.nextInt(); 29 if (i == 886) { 30 break; 31 } else { 32 try { 33 t.check(i); 34 } catch (MyException e) { 35 e.printStackTrace(); 36 break; 37 } 38 39 } 40 41 } 42 } 43 44 }
7、异常使用的注意事项:
下一节 介绍File