异常和异常处理机制
1、什么是异常:
异常是指程序运行过程中发生的一些不正常事件(如除0溢出,数组下标越界,所要读取的文件不存在)
抛出异常:Java程序的执行过程中如果出现异常事件,可以生成一个异常类对象,该对象封装了异常事件的信息,并将其提交给Java运行系统,这个过程称为抛出异常,不出力的话会直接导致程序中断。
注意:
01:Error是无法处理的异常
02:Exception,也就是我们经常见到的一些异常情况,这些异常是我们可以处理的异常,是所有异常类的父类
03:unchecked exception(运行时异常),包括Error和RuntimeException,比如常见的NullPointerException、IndexOutOfBoundsException。
04:典型的RuntimeException包括NullPointerException、IndexOutOfBoundsException、IllegalArgumentException等。
05:典型的非RuntimeException包括IOException、SQLException等。
异常的处理机制
捕获机制:try-catch-finally
try的使用:
01: try不能单独使用,必须和catch或者finally中的其中一个联合使用;
02: 如果执行完try并且不发生异常,则接着去执行finally代码块和finally后面的代码;
03: 如果没有finally代码块,则直接执行catch之后的代码;
04:如果发生异常,则尝试去匹配对应异常的catch代码块。
catch的使用:
01.每一个catch块用于捕获并处理一个特定的异常,或者这异常类型的子类。
02.catch后面的括号定义了异常类型和异常参数。
03.如果异常与之匹配且是最先匹配到的,则虚拟机将使用这个catch块来处理异常。
04.可以书写多个catch代码块!顺序必须是按照异常类型从小到大!
05.在catch块中可以使用异常参数来获取异常的相关信息。异常参数是这个catch块中的局部变量,其它块不能访问
06.如果当前try块中发生的异常在后续的所有catch中都没捕获到,则先去执行finally
08.Java7中可以将多个异常声明在一个catch中
finally的使用:
System.exit(1或者非0):非正常退出,一般放置在catch代码块中
07.如果try中没有发生异常,则所有的catch块将被忽略。
try..catch..finally综合注意点:
- 01.每个代码块中的变量都是局部变量,其他代码块不能访问;
- 02.try不能单独使用,必须和catch或者finally联合使用;
- 03.catch代码块可以有多个,书写顺序必须是按照异常类型的继承关系从小到大书写;
- 04.如果try代码块中出现了return,也是先执行finally之后再执行return
-
try{}语句块:里面是要检测的Java代码,可能会抛出异常,也可能会正常运行(重点放的是会发生错误的代码)
-
catch(异常类型){}块:是当Java运行时,系统接收到try块中所抛出异常对象时,会寻找能处理这一异常catch块来进行处理,注意异常类型需要与try{}语句块可能抛出的异常要匹配。可以有多个catch块。不同的异常类型对应不同的处理代码。
-
finally{}语句块:不管系统有没有抛出异常,都会去执行,一般用来释放资源。除了在之前执行了System.exit(0)
-
在try里面如果发生了异常 会走catch 如果try里面没有捕获到异常的话直接走finally
- 代码环节:
-
public class App { public static void main( String[] args ) { int c=0;//结果接收值 Scanner input =new Scanner(System.in);//输入流 System.out.println("请输入一个数字"); int a =input.nextInt(); System.out.println("请输入二个数字"); int b=input.nextInt(); try { c=a/b; }catch(ArithmeticException e){ e.printStackTrace(); System.out.println("除数不能为零"); }catch(InputMismatchException d){ d.printStackTrace(); System.out.println("输入的类型不匹配"); } finally { System.out.println(c); } } }
异常的分类和异常的结构图
所有异常和错误的父类--Throwable
异常的使用
01.系统自动抛出异常
我们没有使用异常处理机制,系统默认遇到异常时,抛出的异常!
使用throw抛出异常,throws声明异常
throw的使用:
throw new 异常类型([异常提示语句]);
01.异常类型可以是Exception或者其子类;
02.一条throw语句只能抛出一个异常;
4-1.使用try...catch...finally代码块处理异常
4-2.使用throws声明异常,把异常告诉调用者
throws的使用:
方法名称 throws 异常类型1,异常类型2;
01.thows声明在方法名称之后;
异常和异常链的使用
异常链是指将捕获的异常包装进一个新的异常中,新异常中记录了原始异常的信息。并重新抛出的异常处理方式。
丢失异常的场景:
代码环节:
package com.dzq; import java.io.IOException; import java.sql.SQLException; import java.util.InputMismatchException; public class APP2 { public static void main(String[] args) {//快捷键 psvm try { firstException(); }catch (SQLException e){ e.printStackTrace(); } } private static void firstException()throws SQLException { try { secondException(); } catch (IOException e) { e.printStackTrace(); throw new SQLException("=====firstException"); } } private static void secondException() throws IOException{ try { thirdException(); } catch (InputMismatchException e) { e.printStackTrace(); throw new IOException("=====secondException"); } } private static void thirdException() throws InputMismatchException { throw new InputMismatchException("=====thirdException"); } }
异常运行结果:
使用异常链解决丢失根异常的问题:
代码环节:
框架:
代码环节:
package com.dzq.Exception; public class AgeException extends UserException{ public AgeException() { this("密码异常"); } public AgeException(String message) { super(message); } public AgeException(String message, Throwable cause) { super(message, cause); } }
package com.dzq.Exception; public class PassException extends UserException { public PassException() { this("密码异常"); } public PassException(String message) { super(message); } public PassException(String message, Throwable cause) { super(message, cause); } }
package com.dzq.Exception; public class UserException extends RuntimeException{ public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public UserException(String message, Throwable cause) { super(message, cause); } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } private String username; private String password; public UserException() { } public UserException(String message) { super(message); } }
package com.dzq.Exception; public class UserNameException extends UserException { public UserNameException() { this("用户名异常"); } public UserNameException(String message) { super(message); } public UserNameException(String message, Throwable cause) { super(message, cause); } }
package com.dzq.Exception; public class Test { public static void main(String[] args) { /* UserException userException =new UserException(); userException.setUsername("admin"); userException.setPassword("123"); try{ if("admin".equals(userException.getUsername())){ throw new UserNameException(); } }catch (UserNameException e){ System.out.println("用户名异常"); e.getMessage(); }finally { if("123".equals(userException.getPassword())){ throw new PassException(); } } }*/ try{ showName (); }catch (UserNameException e){ e.printStackTrace(); } } public static void showName () throws UserNameException { try { showPassword(); } catch (PassException e) { throw new UserNameException("UserNameException", e); } } private static void showPassword ()throws PassException { try{ showAge(); }catch (AgeException e){ throw new PassException("Password异常",e); } } private static void showAge()throws AgeException{ throw new AgeException("age异常"); } }
自定义异常类
package com.dzq.Exception; public class PassException extends UserException { public PassException() { this("密码异常"); } public PassException(String message) { super(message); } public PassException(String message, Throwable cause) { super(message, cause); } }
package com.dzq.Exception; public class UserException extends RuntimeException{ public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public UserException(String message, Throwable cause) { super(message, cause); } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } private String username; private String password; public UserException() { } public UserException(String message) { super(message); } }
package com.dzq.Exception; public class Test { public static void main(String[] args) { UserException userException =new UserException(); userException.setUsername("admin"); userException.setPassword("123"); try{ if("admin".equals(userException.getUsername())){ throw new UserNameException(); } }catch (UserNameException e){ System.out.println("用户名异常"); e.getMessage(); }finally { if("123".equals(userException.getPassword())){ throw new PassException(); } } }
自定义异常的使用:
自定义异常的注意事项: