快捷搜索:  汽车  科技

不在exception类中的异常有什么(Exception异常)

不在exception类中的异常有什么(Exception异常)异常三种处理方式异常的处理方式:Exception 异常主要分为两类【注】检查异常指:编译器在编译期间要求必须得到处理的那些异常,你必须在编译期处理了。最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。异常机制

Throwable 类是 Java 语言中所有错误或异常的超类。当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。

不在exception类中的异常有什么(Exception异常)(1)

Throwable

含义:异常的英文单词是exception,字面翻译就是“意外、例外”的意思,也就是非正常情况。事实上,异常本质上是程序上的错误,包括程序逻辑错误和系统错误。(开发过程中的语法错误和逻辑错误不是异常)

Error:是Throwable的子类 用于指示合理的应用程序不应该试图捕获的严重问题。是无法处理的异常,比如OutOfMemoryError,一般发生这种异常,JVM会选择终止程序。因此我们编写程序时不需要关心这类异常。

Exception 异常主要分为两类

  1. IOException(I/O 异常),其中 IOException 及其子类异常又被称作「检查异常」
  2. RuntimeException(运行时异常),RuntimeException 被称作「非检查异常」

【注】检查异常指:编译器在编译期间要求必须得到处理的那些异常,你必须在编译期处理了。最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。

不在exception类中的异常有什么(Exception异常)(2)

异常机制

异常的处理方式:

不在exception类中的异常有什么(Exception异常)(3)

异常三种处理方式

try...catch关键字:使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。真正的将异常给处理掉了

不在exception类中的异常有什么(Exception异常)(4)

try-Catch

Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。

一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。

// try...catch 的语法如下 try{ // 程序代码 }catch(异常类型1 异常的变量名1){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 } try { // String line = null; // String line = ""; String line = "abc"; //当JVM执行程序出现了某个异常时就会实例化这个异常并将其抛出 //如果该异常没有被异常处理机制控制,则JVM会将异常隐式抛出当方法外(这里是main方法外) System.out.println(line.length()); System.out.println(line.charAt(0)); System.out.println(Integer.parseInt(line)); //若try语句块中某句话出错了,则剩下的代码都不会执行! System.out.println("!!!!!!!!!!!!!!!!"); }catch(NullPointerException e){ System.out.println("出现了空指针!"); //catch可以定义多个,当try中不同的异常有不同处理办法时可分开捕获并处理 }catch(StringIndexOutOfBoundsException e){ System.out.println("出现了下标越界!"); } //若某些异常的处理方式相同时,可以合并在一个catch来处理 try { String line = "abc"; //当JVM执行程序出现了某个异常时就会实例化这个异常并将其抛出 //如果该异常没有被异常处理机制控制,则JVM会将异常隐式抛出当方法外(这里是main方法外) System.out.println(line.length()); System.out.println(line.charAt(0)); System.out.println(Integer.parseInt(line)); //若try语句块中某句话出错了,则剩下的代码都不会执行! System.out.println("!!!!!!!!!!!!!!!!"); }catch(NullPointerException|StringIndexOutOfBoundsException e){ System.out.println("出现了空指针或下标越界并处理了!"); //可以在下面catch超类异常来捕获并处理这一类异常。 }catch(Exception e){ System.out.println("反正就是出了个错"); }

return:当代码中出现return时,一定是finally语句块执行完成之后,才会去执行相应的return代码。无论这条return语句放在什么位置。

不在exception类中的异常有什么(Exception异常)(5)

return执行流程图

finally关键字:无论是否发生异常,finally代码块中的代码总会被执行。在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。真正的将异常给处理掉了

// try...catch...finally 的语法如下 try{ // 程序代码 }catch(异常类型1 异常的变量名1){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }finally{ // 程序代码 } //不管try里面是否异常,都会执行finally中的代码块 try{ String line = null; System.out.println(line.length()); return; //----------------------上面return执行流程图很好的解释了 }catch(Exception e){ System.out.println("出错了!"); }finally{ System.out.println("finally中的代码执行了!"); }

自动关闭特性,JDK7之后,java提供了一个新的特性:自动关闭。旨在IO操作中可以更简洁的使用异常处理机制完成最后的close操作。【注意】语法中可在try的"()"中定义的并初始化的对象必须实现了java.io.AutoCloseable接口 否则编译不通过.

// 自动关闭 语法: try( 定义需要在finally中调用close()方法关闭的对象. ){ IO操作 }catch(XXXException e){ ... } //下面代码是编译器认可的,而不是虚拟机。 // 编译器在编译上述代码后会在编译后的class文件中改回原本的写法 try( FileOutputStream fos = new FileOutputStream("fos.dat"); ){ fos.write(1); } catch (IOException e) { e.printStackTrace();//向控制台输出当前异常的错误信息 }

throws和thow关键字:如果一个方法没有捕获一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。

  【注】throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由方法去处理异常,真正的处理异常由此方法的上层调用处理。

throw通常下面两种情况我们主动对外抛出异常:throw关键字的一个非常重要的作用就是 异常类型的转换.

  • 1:当程序遇到一个满足语法,但是不满足业务要求时,可以抛出一个异常告知调用者。
  • 2:程序执行遇到一个异常,但是该异常不应当在当前代码片段被解决时可以抛出给调用者。

throws当一个方法中使用throw抛出一个非RuntimeException的异常时,就要在该方法上使用throws声明这个异常的抛出。此时调用该方法的代码就必须处理这个异常,否则编译不通过。允许throws后面跟着多个异常类型;处理手段有下面两种方式:

  1. --使用try-catch捕获并处理这个异常
  2. ---在当前方法(本案例就是main方法)上继续使用throws声明该异常的抛出给调用者解决。 具体选取那种取决于异常处理的责任问题。

public class Person { private int age; public int getAge() { return age; } //当一个方法使用throws声明异常抛出时 调用此方法的代码片段就必须处理这个异常 public void setAge(int age) throws Exception { if(age<0 || age>100){ //使用throw对外抛出一个异常 // throw new RuntimeException("年龄不合法!"); //除了RuntimeException之外 抛出什么异常就要在方法上声明throws什么异常 throw new Exception("年龄不合法!"); } this.age = age; } } // 【注意】 永远不应当在main方法上使用throws!! try { Person p = new Person(); /* 当我们调用一个含有throws声明异常抛出的方法时 编译器要求 我们必须添加处理异常的手段 否则编译不通过.而处理手段有两种 1:使用try-catch捕获并处理异常 2:在当前方法上继续使用throws声明该异常的抛出 具体用哪种取决于异常处理的责任问题 */ p.setAge(100000);//典型的符合语法,但是不符合业务逻辑要求 System.out.println("此人年龄:" p.getAge() "岁"); } catch (Exception e) { e.printStackTrace(); }

子类重写超类含有throws声明异常抛出的方法时对throws的几种特殊的重写规则

public class ThrowsDemo { public void dosome()throws IOException AWTException {} } class SubClass extends ThrowsDemo{ // public void dosome()throws IOException AWTException {} //可以不再抛出任何异常 // public void dosome(){} //可以仅抛出部分异常 // public void dosome()throws IOException {} //可以抛出超类方法抛出异常的子类型异常 // public void dosome()throws FileNotFoundException {} //不允许抛出额外异常(超类方法中没有的 并且没有继承关系的异常) // public void dosome()throws SQLException {} //不可以抛出超类方法抛出异常的超类型异常 // public void dosome()throws Exception {} }

可检测异常,非检测异常

  1. 可检测异常:可检测异常经编译器验证,对于声明抛出异常的任何方法,编译器将强制执行处理或声明规则,不捕捉这个异常,编译器就通不过,不允许编译
  2. 非检测异常:非检测异常不遵循处理或者声明规则。在产生此类异常时,不一定非要采取任何适当操作,编译器不会检查是否已经解决了这样一个异常
  3. RuntimeException 类属于非检测异常,因为普通JVM操作引起的运行时异常随时可能发生,此类异常一般是由特定操作引发。但这些操作在java应用程序中会频繁出现。因此它们不受编译器检查与处理或声明规则的限制。

try { String str = "abc"; System.out.println(Integer.parseInt(str)); } catch (NumberFormatException e) { //异常最常用的方法 用于将当前错误信息输出到控制台 e.printStackTrace(); //获取错误消息.记录日志的时候或提示给用户可以使用它 String message = e.getMessage(); System.out.println(message); }

自定义异常类

  • 一般地,用户自定义异常类都是RuntimeException的子类
  • 自定义异常类通常需要编写几个重载的构造器
  • 自定义异常需要提供serialVersionUID
  • 自定义的异常通过throw抛出
  • 自定义异常最重要的是异常类的名字,当异常出现时,可以根据名字判断异常类型。

注意以下问题:

  1. * :定义的类名要做到见名知义
  2. * :必须是Exception的子类 继承于现有的异常结构:RuntimeException、Exception
  3. * :提供Exception所定义的所有构造方法
  4. * :提供全局常量:serialVersionUID (非必要)

//自定义 异常类 继承 Exception 并且重写里面的构造方法 public class IllegalAgeException extends Exception{ public IllegalAgeException() { } public IllegalAgeException(String message) { super(message); } public IllegalAgeException(String message Throwable cause) { super(message cause); } public IllegalAgeException(Throwable cause) { super(cause); } public IllegalAgeException(String message Throwable cause boolean enableSuppression boolean writableStackTrace) { super(message cause enableSuppression writableStackTrace); } }

【总结】异常处理机制是用来处理那些可能存在的异常,但是无法通过修改逻辑完全规避的场景。而如果通过修改逻辑可以规避的异常是bug,不应当用异常处理机制在运行期间解决!应当在编码时及时修正。

学习记录,如有侵权请联系删除。

猜您喜欢: