一、异常概述
1、定义:在程序执行过程中发生的不正常情况称为“异常”(开发过程中的语法错误和逻辑错误不是异常)。
2、异常事件可分为两类:
2.1、Error:Java虚拟机无法解决的严重问题。例如:JVM系统内部错误、资源耗尽等情况。比如:StackOverflowError和OOM。
public class ErrorTest { public static void main(String[] args) { //1、栈溢出:java.lang.StackOverflowError // main(args); //2、堆溢出:java.lang.OutOfMemoryError Integer[] arr = new Integer[1024*1024*1024]; } }
2.2、Exception:因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:空指针访问、网络连接中断、数组角标越界·····
二、异常体系结构
java.lang.Throwable
|--------java.lang.Error:一般不写针对性的代码进行处理。
|--------java.lang.Exception:可以进行异常处理。
|--------编译时异常(checked)
|--------IOException
|-------FileNoteFondException
|--------ClassNoteFondException
|--------运行时异常(unchecked)
|--------NullPointException
|--------ArrayIndexOutOfBoundsException
|--------NumberFormatException
|--------ClassCastException
|--------InputMismatchException
|--------ArithmeticException
import java.util.Date; import java.util.Scanner; public class ExceptionTest { public static void main(String[] args) { /* * // java.lang.NullPointerException int[] arr = null; * System.out.println(arr[2]); */ /* * // java.lang.ArrayIndexOutOfBoundsException * int[] arr = new int[10]; * System.out.println(arr[10]); * // java.lang.ArrayIndexOutOfBoundsException * String str = "abc"; * System.out.println(str.charAt(3)); */ /* * //java.lang.ClassCastException * Object obj = new Date(); * String str =(String)obj; */ /* * //java.lang.NumberFormatException * String str = "abc"; * int num =Integer.parseInt(str); */ //java.util.InputMismatchException // Scanner scanner = new Scanner(System.in); // int scor = scanner.nextInt();//输入不同类型的 // System.out.println(scor); //java.lang.ArithmeticException int a = 10; int b = 0; System.out.println(a/b); } }
三、异常处理机制
1、抓抛模型
1.1、过程一:“抛”:程序正在执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象。并将此对象抛出。一旦抛出异常对象后,气候的代码就不再执行。
关于异常对象的产生:1??系统自动生成的异常对象。
2??手动生成一个对象并抛出(throw)。
1.2、过程二:“抓”:可以理解为异常的处理方式:1、try - catch - finally 2、throws
2、异常处理的方式一:try - catch - finally 结构
2.1、格式:
try{
可能出现异常的代码
}catch(异常类型1 变量名1){
处理异常的方式1
}catch(异常类型2 变量名2){
处理异常的方式2
}catch(异常类型2 变量名2){
处理异常的方式3
· }
···········
finally{
一定会执行的代码
}
2.2、说明:
2.2.1、finally是可选的。
2.2.2、使用try将可能出现异常代码包起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型去catch中进行匹配。
2.2.3、一旦try中的异常对象匹配到某一个catch时就进入catch中进行异常处理,一旦处理完成,跳出当前的try-catch结构(在没写finally的情况下)。继续执行之后的代码。
2.2.4、catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下都无所谓。
catch中的异常类型如果满足子父类关系,则子类一定声明在父类上面。否则报错。
2.2.5、常用异常对象处理方式:1??、获取异常信息:异常对象.getMessage()
2??、获取堆栈信息:异常对象.printStackTrace()。
2.2.6、在try结构中定义的变量,在try结构外不能被调用。
2.2.7、try - catch - finally 结构可以嵌套。
2.3、finally的使用
2.3.1、finally是可选的。
2.3.2、finally中声明的是一定会被执行的代码。即使出现 catch中又出现了异常、try中有return语句、catch中有return语句等情况。
2.3.3、像数据库链接、输入输出流、网络编程Socket等资源,JVM是不能自动回收的,我们需要自己手动进行资源释放。此时的资源释放就要声明在finally中。
2.4、体会
2.4.1、使用try - catch - finally处理编译时异常,是让程序在编译时就不再报错,但是运行时仍可能报错。相当于我们使用try - catch - finally将一个编译时可能出现的异常,延迟到运行时出现。
2.4.2、开发中,由于运行时异常比较常见,所以我们通常不针对运行时异常编写try - catch - finally。针对编译时异常,我们一定要考虑异常处理。
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class ExceptionTest1 { public static void main(String[] args) { ExceptionTest1 et = new ExceptionTest1(); // et.method(); et.method1(); } public void method() { String str = "123"; str = "abc"; try { int num = Integer.parseInt(str); } catch (NumberFormatException e) { System.out.println("数值转换异常"); System.out.println(e.getMessage()); /* * int[] arr = new int[10]; System.out.println(arr[10]); */ return; } catch (NullPointerException e) { System.out.println("空指针异常了"); e.getStackTrace(); } finally { System.out.println("我还是会执行"); } } public void method1() { File file = new File("hello.txt"); FileInputStream fis = null; try { fis = new FileInputStream(file); int data = fis.read(); while (data != -1) { System.out.print((char) data); data = fis.read(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fis != null) { fis.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
3、异常处理的方式二:throws + 异常类型
3.1、“throws + 异常类型”写在方法的声明处。指明此方法执行时可能会抛出的异常类型。在方法体执行时出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常类型时,就会被抛出。异常代码后的内容不再执行。
3.2、与try - catch - finally的区别:
3.2.1、try - catch - finally是真正的将异常处理掉了。
3.2.2、throws的方式只是把异常抛给了方法的调用者。并没有真正将异常处理。
package com.oldking.java; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class ExceptionTest2 { public static void main(String[] args) { try { method2(); } catch (IOException e) { e.printStackTrace(); } } public static void method2() throws IOException { method(); } public static void method() throws FileNotFoundException, IOException { File file = new File("hello.txt"); FileInputStream fis = new FileInputStream(file); int data = fis.read(); while (data != -1) { System.out.print((char) data); data = fis.read(); } fis.close(); System.out.println("123456"); } }
3.3、开发中如何选择try - catch - finally还是throws?
3.3.1、如果父类中被重写的方法没有用throws方式处理异常,则子类重写的方法也不能用throws,此时子类中若有异常出现,只能用try - catch - finally方式处理。
3.3.2、执行的方法A中,先后又调用了其他的几个方法,这几个方法是递进关系执行的。我们建议这几个方法用throws的方式进行处理。而执行的方法A可以考虑使用try-catch-finally方式进行处理。
4、方法重写时与异常相关的规则:子类重写的方法抛出的异常类型范围不能大于父类被重写方法抛出异常的异常类型。
5、手动抛出异常
public class ExceptionTest3 { public static void main(String[] args) { Student s = new Student(); try { s.setId(-1); } catch (RuntimeException e) { e.printStackTrace(); } } } class Student { private int id; public void setId(int id) throws RuntimeException { if (id > 0) { this.id = id; } else { // System.out.println("错误参数"); //手动抛出异常 throw new RuntimeException("参数错误!"); } } }
四、自定义异常
1、如何自定义异常
1.1、继承于现有的异常结构:RunTimeException、Exception。
1.2、提供全局常量:serialVersionUID
public class MyException extends RuntimeException { public static void main(String[] args) { Students s = new Students(); s.setId(-1); } static final long serialVersionUID = -703489719074576939L; public MyException() { } public MyException(String msg) { super(msg); } } class Students { private int id; public void setId(int id) { if (id > 0) { this.id = id; } else { // System.out.println("错误参数"); // 手动抛出异常 throw new MyException("参数错误!"); } } }
原文:https://www.cnblogs.com/Oldking666/p/14580146.html