Java中异常的捕获及处理

Java异常的捕获及处理

  • 一、Java异常简介
  • 二、处理异常
    • 捕获异常
    • 异常处理流程
    • 抛出异常
    • 三种类型的异常
  • 三、Java异常的分类
  • 四、自定义异常

一、Java异常简介

什么是异常?

程序在运行的时候,发生的不被期望的问题,它阻止了程序按照程序员的预期正常执行,这就是异常。在异常发生的时候,是任程序自生自灭,立刻退出终止。在Java中,即为Java在编译或运行或者运行过程中出现的错误。

Java提供了更为优秀的解决方法:异常处理机制

异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。
Java中的异常不仅可以是函数中的语句执行时引发的,也可以是程序员通过throw 语句手动抛出的,只要在Java程序中产生了异常,就会用一个对应类型的异常对象来封装异常,JRE就会试图寻找异常处理程序来处理异常。

异常的好处:

例如, 我们用伪代码演示一下开始一局王者荣耀的过程。
LBYL 风格的代码(不使用异常)

boolean ret = false;
ret = 登陆游戏();
if (!ret) {
 处理登陆游戏错误;
    return;
}
ret = 开始匹配();
if (!ret) {
 处理匹配错误;
    return;
}
ret = 游戏确认();
if (!ret) {
 处理游戏确认错误;
    return;
}

EAFP 风格的代码(使用异常)

try {
    登陆游戏();
    开始匹配();
    游戏确认();
    选择英雄();
    载入游戏画面();
   ...
} catch (登陆游戏异常) {
    处理登陆游戏异常;
} catch (开始匹配异常) {
 处理开始匹配异常;
} catch (游戏确认异常) {
 处理游戏确认异常;
} catch (选择英雄异常) {
 处理选择英雄异常;
} catch (载入游戏画面异常) {
 处理载入游戏画面异常;
}
......

二、处理异常

Java异常机制用到的几个关键字:trycatchfinallythrowthrows

捕获异常

基本语法:

try{
 有可能出现异常的语句 ;
}[catch (异常类型 异常对象) {
} ... ]
[finally {
 异常的出口
}]
  • try 代码块中放的是可能出现异常的代码。
  • catch 代码块中放的是出现异常后的处理行为。
  • finally 代码块中的代码用于处理善后工作, 会在最后执行。其中 catch 和 finally 都可以根据情况选择加或者不加。

异常处理流程

  • 程序先执行 try 中的代码
  • 如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配.
  • 如果找到匹配的异常类型, 就会执行 catch 中的代码
  • 如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者.
  • 无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行).
  • 如果上层调用者也没有处理的了异常, 就继续向上传递,一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止

注意事项:

  • catch 不能独立于 try 存在。
  • catch里面不能没有内容
  • try, catch, finally 块之间不能添加任何代码。
  • finally里面的代码最终一定会执行
  • 如果程序可能存在多个异常,需要多个catch进行捕获。

抛出异常

除了 Java 内置的类会抛出一些异常之外, 程序猿也可以手动抛出某个异常. 使用 throw 关键字完成这个操作

public static void main(String[] args) {
 System.out.println(divide(10, 0));
}
public static int divide(int x, int y) {
 if (y == 0) {
 throw new ArithmeticException("抛出除 0 异常");
 }
 return x / y;
}
// 执行结果
Exception in thread "main" java.lang.ArithmeticException: 抛出除 0 异常

三种类型的异常

  • 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。

  • 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。

  • 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

三、Java异常的分类

异常的根接口Throwable,其下有2个子接口,Error和Exception。

Error:指的是JVM错误,这时的程序并没有执行,无法处理;
Exception:指的是程序运行中产生的异常,用户可以使用处理格式处理。
Java中异常的捕获及处理_第1张图片

顶层类 Throwable 派生出两个重要的子类, Error 和 Exception
其中 Error 指的是 Java 运行时内部错误和资源耗尽错误,应用程序不抛出此类异常。 这种内部错误一旦出现,除了告知用户并使程序终止之外, 再无能无力,这种情况很少出现。
Exception 是我们程序猿所使用的异常类的父类。其中 Exception 有一个子类称为 RuntimeException , 这里面又派生出很多我们常见的异常类NullPointerException , IndexOutOfBoundsException 等。

throwthrows都是在异常处理中常用的关键字,区别:

throw:指的是在方法中人为抛出一个异常对象(这个异常对象可能是自己实例化时已存在的);
throws:在方法的声明上使用,表示此方法在调用时必须处理异常。

四、自定义异常

在 Java 中可以自定义异常。如果要自定义异常类,则扩展Exception类即可
例如,实现一个用户登录功能

class UserError extends Exception {
 public UserError(String message) {
 super(message);
 }
}
class PasswordError extends Exception {
 public PasswordError(String message) {
 super(message);
 }
}
public static void main(String[] args) {
 try {
 login("admin", "666666");
 } catch (UserError userError) {
 userError.printStackTrace();
 } catch (PasswordError passwordError) {
 passwordError.printStackTrace();
 }
}
public static void login(String userName, String password) throws UserError,
PasswordError {
 if (!TestDemo.userName.equals(userName)) {
 throw new UserError("用户名错误");
 }
 if (!TestDemo.password.equals(password)) {
 throw new PasswordError("密码错误");
 }
 System.out.println("登陆成功!");
}

注意事项:

  • 自定义异常通常会继承自 Exception 或者 RuntimeException
  • 继承自 Exception 的异常默认是受查异常
  • 继承自 RuntimeException 的异常默认是非受查异常

你可能感兴趣的:(java,java,编程语言,intellij,idea)