java基础---异常处理
异常处理
在Java语言中, 将程序执行中发生的不正常情况称为“异常” ,开发中的语法错误和逻辑错误不是异常,属于java.lang.throwable 里
- 分类:
- error: java虚拟机无法解决的严重问题。如JVM系统内部错误,资源耗尽等严重情况。如 StackOverflowError和 OutOfMemoryError,一般不编写针对性代码进行处理
- Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性代码进行处理。例如:空指针,视图读取不存在的文件,网络连接中断,数组越界等
- error: java虚拟机无法解决的严重问题。如JVM系统内部错误,资源耗尽等严重情况。如 StackOverflowError和 OutOfMemoryError,一般不编写针对性代码进行处理
- 捕获错误最理想的在编译期间,但有的错误只有在运行时才会发生,如除数为0,数组越界等
- Exception的分类:编译时异常和运行时异常(非检测异常)
- 运行时异常:
- NullPointerException
- IndexOutOfBoundsException
- ClassCastException
- NumberFormatException
- InputMismatchException
- ArithmeticException
- 编译时异常:
- IOException:FileNotFoundException
- ClassNotFoundException
- 运行时异常:
public class ExceptionTest { //******************以下是编译时异常*************************** @Test public void test7(){ // 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(); } //******************以下是运行时异常*************************** //ArithmeticException @Test public void test6(){ int a = 10; int b = 0; System.out.println(a / b); } //InputMismatchException @Test public void test5(){ Scanner scanner = new Scanner(System.in); int score = scanner.nextInt(); System.out.println(score); scanner.close(); } //NumberFormatException @Test public void test4(){ String str = "123"; str = "abc"; int num = Integer.parseInt(str); } //ClassCastException @Test public void test3(){ Object obj = new Date(); String str = (String)obj; } //IndexOutOfBoundsException @Test public void test2(){ //ArrayIndexOutOfBoundsException // int[] arr = new int[10]; // System.out.println(arr[10]); //StringIndexOutOfBoundsException String str = "abc"; System.out.println(str.charAt(3)); } //NullPointerException @Test public void test1(){ // int[] arr = null; // System.out.println(arr[3]); String str = "abc"; str = null; System.out.println(str.charAt(0)); } }
- 异常的处理:抓抛模型
- "抛":在某些特殊情况下有些异常不能处理或者不便于处理时,就可以将该异常转移给该方法的调用者,当方法执行时出现异常,则底层生成一个异常类对象抛出,异常代码后续对的代码不再执行
- “抓”:异常的处理方式:① try-catch-finally ② throws
一、异常捕获 try-catch-finally
语法格式 try { 编写可能发生异常的代码; } catch(异常类型 引用变量名) { 编写针对该类异常的处理代码; } ... finally { 编写无论是否发生异常都要执行的代码; }
- finally是可选的。
- 使用try可以将异常代码块包装起来,在执行过程中一旦出现议程就会生成一个对应异常类的对象,根据对象类型去catch中进行匹配
- 一旦try中异常对象匹配到catch,进入catch中进行异常处理,执行完毕跳出try-catch结构(无finally情况)
- 小异常写在大异常前面
- catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面。否则,报错
- 常用的异常对象处理的方式: ① String getMessage() ② printStackTrace()getMessage()
- getMessage():获取异常信息,返回字符串
- printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
- try中声明的变量出了try结构就不能再被调用
- try-catch-finally支持嵌套,捕获的异常在运行时仍然可能出现一次
- finally中声明的是一定会被执行的代码。即使catch中又出现异常了,try中有return语句,catch中有return语句等情况。
二、异常抛出 thows+异常类型
在某些特殊情况下有些异常不能处理或者不便于处理时,就可以将该异常转移给该方法的调用者,当方法执行时出现异常,则底层生成一个异常类对象抛出,异常代码后续对的代码不再执行
访问权限 返回值类型 方法名称(形参列表) throws 异常类型1,异常类型2,...{ 方法体; } 如: public void show() throws IOException{}
- 重写方法不能抛出比被重写方法范围更大的异常类型。 在多态的情况下,对methodA()方法的调用-异常的捕获按父类声明的异常处理
- 子类重写的方法不能抛出更大的异常、不能抛出平级不一样的异常,但可以抛出一样的异常、更小的异常以及不抛出异常
public class A { public void methodA() throws IOException { …… } } public class B1 extends A { public void methodA() throws FileNotFoundException { …… } } public class B2 extends A { public void methodA() throws Exception { //报错 …… } }
- 若父类中被重写的方法没有抛出异常时,则子类中重写的方法只能进行异常的捕获处理。
- 若一个方法内部又以递进方式分别调用了好几个其它方法,则建议这些方法内可以使用抛出的方法处理到最后一层进行捕获方式处理
三、自定义异常
当需要在程序中表达年龄不合理的情况时,而Java官方又没有提供这种针对性的异常,此时就需要程序员自定义异常加以描述
- 首先要生成异常类对象, 然后通过throw语句实现抛出操作(提交给Java运行环境) ,可以抛出的异常必须是Throwable或其子类的实例
- 用户自定义异常类
- 自定义xxxException异常类继承Exception类或者其子类。
- 提供两个版本的构造方法,一个是无参构造方法,另外一个是字符串作为参数的构造方法。
- 自定义异常需要提供全局常量:serialVersionUID
- 自定义异常最重要的是异常类的名字,当异常出现时,可以根据名字判断异常类型。例如:throw new 异常类型(实参);
public class MyException extends Exception{ static final long serialVersionUID = -7034897193246939L; public MyException(){ } public MyException(String msg){ super(msg); } }
四、执行顺序
public class ReturnExceptionDemo { static void methodA() { try { System.out.println("进入方法A"); throw new RuntimeException("制造异常"); //异常被抛出了 } finally { System.out.println("用A方法的finally"); } } static void methodB() { try { System.out.println("进入方法B"); return; } finally { System.out.println("调用B方法的finally"); } } public static void main(String[] args) { try { methodA(); //接收到被抛出的异常:制造异常 } catch (Exception e) { System.out.println(e.getMessage()); //捕获处理 } methodB(); } } //输出为 /*进入方法A 用A方法的finally 制造异常 进入方法B 调用B方法的finally */
浙公网安备 33010602011771号