第五章 异常处理
Java程序设计第五章 异常处理
1.异常的概述与异常的体系结构
-
外部原因导致程序异常:比如客户输入数据格式,读取文件是否存在,网络是否始终保持通畅。
-
异常:在Java语言中,将程序执行中发生的不正常的情况称之为异常,但是开发过程中语法错误和逻辑错误不是异常
-
Error:java虚拟机无法解决的严重问题。JVM系统内部错误、资源耗尽严重情况。
public class ErrorDemo01 { public static void main(String[] args) { // 栈溢出java.lang.*Error main(args); } }
-
Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理,例如空指针访问,试图读取不存在的文件,网络连接中断,数据下标越界等等
-
出现错误通常表明出现了异常,但是出现异常却比一定出现了错误
-
异常的分类
-
2.常见的异常举例
-
空指针异常 NullPointException
public class ExceptionDemo01 { public static void test1(){ int[] arr = null; System.out.println(arr[3]); } public static void main(String[] args) { test1(); } }
public class ExceptionDemo01 { public static void test2(){ String str = "abc"; str = null; // charAt(0)寻找该字符串的第0个字符 System.out.println(str.charAt(0)); } public static void main(String[] args) { test2(); } }
-
数组角标越界 java.lang.ArrayIndexOutOfBoundsException
public class ExceptionDemo01 { public static void test3() { int[] arr = new int[3]; System.out.println(arr[3]); } public static void main(String[] args) { test3(); } }
-
类型转换异常java.lang.ClassCastException
import java.util.Date; public class ExceptionDemo01 { public static void test4() { Object obj = new Date(); String str = (String)obj; } public static void main(String[] args) { test4(); } }
-
数字格式异常java.lang.NumberFormatException
public class ExceptionDemo01 { public static void test5() { String str = "abc"; int num = Integer.parseInt(str); } public static void main(String[] args) { test5(); } }
-
输入不匹配异常java.util.InputMismatchException
import java.util.Scanner; public class ExceptionDemo01 { public static void test6() { Scanner scanner = new Scanner(System.in); int score = scanner.nextInt(); // 比如输入一个字符串就会出现该异常 System.out.println(score); } public static void main(String[] args) { test6(); } }
-
算数异常java.lang.ArithmeticException
public class ExceptionDemo01 { public static void test7() { int a = 10; int b = 0; System.out.println(a/b); } public static void main(String[] args) { test7(); } }
-
编译型异常举例
import java.io.File; import java.io.FileInputStream; import java.io.IOException; //如果没有抛出IOExceotion出现编译型异常不会生成java字节码文件 public class ExceptionDemo02 { public void test1() throws IOException { File file = new File("hello.txt"); FileInputStream fis = new FileInputStream(file); int data = fis.read(); while (data !=-1){ System.out.println((char)data); data = fis.read(); } fis.close(); } }
3.异常处理机制一:try-catch-finally
异常处理抓抛模型
-
“抛”,程序在正常执行的过程中,一旦出现异常,就会在异常代码中生成一个对应异常类对象,并将此对象抛出,一旦抛出对象以后,其后代码就不会执行
-
“抓”,可以理解为异常的处理方式,try-catch-finally,throws
try{ //可能出现异常的代码 }catch(异常类型1,变量名1){ //处理异常的方式一 }catch(异常类型2,变量名2){ //处理异常的方式二 }catch(异常类型3,变量名3){ //处理异常的方式三 } ··· finally{ //一定会执行的代码 }
-
try-catch举例
//finally是可选的 //使用try将可能出现异常的代码包装起来,在其执行过程中,一旦出现异常,就会生成对应异常类的对象,根据此对象的类型,在catch中进行匹配 //一旦try中的对象匹配到一个catch时我们就进入catch中进行处理,一旦处理完成就跳出当前try-catch结构 //在try结构中声明的变量,在出了try结构以后,就不能在被调用 //try - catch结构处理编译时异常,使得程序在编译时就不再报错,但是运行时仍可能报错 //try - catch结构根据需要可以嵌套 public class ExceptionDemo03 { public static void test1(){ String str = "123"; str = "abc"; // 将num定义到try结构的外面即可 int num =0 ; try{ num = Integer.parseInt(str); System.out.println("hello..........1"); }catch (NullPointerException e){ System.out.println("出现空指针异常,不要着急......"); }catch (NumberFormatException e){ // 输出异常两种方式 System.out.println("出现数值转换异常,不要着急....."); System.out.println(e.getMessage()); // 包含getmessagehai而且还会显示那些结构出现问题 e.printStackTrace(); }catch (Exception e){ System.out.println("出现异常,不要急......"); } System.out.println(num); System.out.println("hello................2"); } public static void main(String[] args) { test1(); } }
-
finally的使用
public class FinallyDemo01 { // finally声明的是一定会被执行的代码,即使try或者catch中有return语句也会执行 public static void test1(){ try{ int a = 10; int b = 0; System.out.println(a/b); }catch (AbstractMethodError e){ e.printStackTrace(); }catch (Exception e){ e.printStackTrace(); }finally { System.out.println("hello"); } } public static void main(String[] args) { test1(); } }
像数据库连接,输入输出流,网络编程的Socket等资源,JVM是不是自动回收,需要自己手动的资源释放,资源的释放操作就需要声明到finally使其一定被释放
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class FinallyDemo02 { // IO流的异常处理操作 public static void test2(){ FileInputStream fis = null; try { File file = new File("hello.txt"); fis = new FileInputStream(file); int data = fis.read(); while (data != -1){ System.out.println((char)data); data = fis.read(); } }catch (FileNotFoundException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); }finally { // 如果没有这个判断语句将会出现空指针异常 if (fis != null){ // 自己本身也可能出异常 try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static void main(String[] args) { test2(); } }
-
实际开发过程中运行时异常比较常见,通常就不针对运行时异常编写try-catch,因为你捕获异常之后也不能解决问题,直接改代码,但是编译型异常一定要用try-catch。
4.异常处理机制二:throws
-
try-catch-finally是真正将异常处理掉,但是throws方式只是将异常抛给了方法的调用者,并没有处理异常
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; // throws+异常类型处理方式,写在方法的声明处,指明此方法执行时,可能会出现的异常类型 //try-catch才是处理异常,throws只是甩锅不能解决异常,异常代码后续的代码就不会执行 public class ThrowsDemo01 { // main方法需要自己处理,把异常处理掉,不然jvm会出现问题 public static void main (String[]args) throws IOException { try{ method2(); }catch (FileNotFoundException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } } // 方法二往main方法甩锅 public static void method2() throws FileNotFoundException,IOException { method1(); } // 方法一往上面甩锅 public static void method1() throws FileNotFoundException, IOException { FileInputStream fis = null; File file = new File("hello.txt"); fis = new FileInputStream(file); int data = fis.read(); while (data != -1) { System.out.println((char) data); data = fis.read(); } fis.close(); System.out.println("hello......."); } }
-
子类重写方法抛出的异常不大于父类被重写方法抛出的异常类型
-
如果父类被重写的方法没有throws方式处理异常,则子类重写的方法也不能用throws,只能用try-catch-finally抛出异常
-
执行的方法中先后调用了另外几个方法,这几个方法是递进关系则使用throws方法处理,而执行方法用try-catch-finally处理异常
5.手动抛出异常:throw
-
产生异常的两种方式:一是系统自动生成的异常,二是手动生成异常,并抛出(throw)
public class ThrowStudentText { public static void main(String[] args) { Student s = new Student(); // 处理异常 try { s.regist(-1); System.out.println(s); } catch (Exception e) { System.out.println(e.getMessage()); } } } class Student { private int id; // 将手动抛出的异常处理上抛给main方法处理 public void regist(int id) throws Exception{ if (id>0){ this.id = id ; }else{ // 手动抛出编译时异常 throw new Exception("您输入的数据非法!"); } } }
6.用户自定义异常类
-
用户自定义异常都是直接继承RuntimeException、Exception
class MyExceptionDemo01 { public static void main(String[] args) throws MyException { execute("java"); } public static void execute(String a) throws MyException { System.out.println("execute......."); if ("java".equals(a)){ throw new MyException("参数不能为java"); } } // 自定义异常类继承Exception public static class MyException extends Exception{ // 提供重载的构造器 public MyException(){ super(); } public MyException(String msg){ // 还原父类的调用 super(msg); } } }
上一篇: 求第k小元素