主页
  • 主页
  • 分类
  • 热文
  • 教程
  • 面试
  • 标签
Java

Java 基础

Java 主页
Java 概述
Java 历史
Java 功能
Java 与 C++
Java JVM(Java虚拟机)
Java JDK、JRE 和 JVM
Java Hello World 程序
Java 环境设置
Java 基本语法
Java 变量类型
Java 数据类型
Java 类型转换
Java Unicode 系统
Java 基本运算符
Java 注释
Java 用户输入
Java 日期和时间

Java 控制语句

Java 循环控制
Java 决策结构
Java if-else 语句
Java switch 语句
Java for 循环
Java for each 循环
Java while 循环
Java do...while 循环
Java break 语句
Java continue 语句

Java 面向对象编程

Java OOP概念
Java 类和对象
Java 类属性
Java 类方法
Java 方法
Java 变量作用域
Java 构造函数
Java 访问修饰符
Java 继承
Java 聚合
Java 多态
Java 覆盖
Java 方法重载
Java 动态绑定
Java 静态绑定
Java 实例初始化块
Java 抽象
Java 封装
Java 接口
Java 包
Java 内部类
Java 静态类
Java 匿名类
Java 单例类
Java 包装类
Java 枚举类
Java 枚举构造函数
Java 枚举字符串

Java 内置类

Java 数字
Java 布尔值
Java 字符
Java 数组
Java 数学类

Java 文件处理

Java 文件
Java 创建文件
Java 写入文件
Java 读取文件
Java 删除文件
Java 目录操作
Java I/O流

Java 错误和异常

Java 异常
Java Try Catch
Java try-with-resources
Java 多个 Catch
Java 嵌套 try
Java finally
Java 抛出异常
Java 异常传播
Java 内置异常
Java 自定义异常

Java 多线程

Java 多线程
Java 线程生命周期
Java 创建线程
Java 启动线程
Java 加入线程
Java 命名线程
Java 线程调度
Java 线程池
Java 主线程
Java 线程优先级
Java 守护线程
Java 线程组
Java JVM 关闭

Java 同步

Java 线程同步
Java 块同步
Java 静态同步
Java 线程间通信
Java 线程死锁
Java 中断线程
Java 线程控制
Java 可重入锁

Java 网络

Java 网络编程
Java 套接字编程
Java URL 处理
Java URL 类
Java URLConnection 类
Java HttpURLConnection 类
Java Socket 类
Java 泛型

Java 集合

Java 集合框架
Java 集合接口

Java 接口

Java 列表接口
Java 队列接口
Java 映射接口
Java SortedMap 接口
Java 集合(Set)接口
Java SortedSet 接口

Java 数据结构

Java 数据结构
Java 枚举接口

Java 集合算法

Java 迭代器
Java 比较器
Java Comparable 接口

Java 高级

Java 命令行参数
Java Lambda 表达式
Java 发送电子邮件
Java 小应用程序
Java Javadoc
Java 自动装箱和拆箱
Java mismatch() 方法
Java REPL
Java 多版本发布 JAR
Java 私有接口方法
Java 金刚石操作符
Java 多分辨率图像 API
Java 集合的工厂方法
Java 模块系统
Java Nashorn 引擎
Java Optional 类
Java 方法引用
Java 功能接口
Java 默认方法
Java Base64 工具类
Java Switch 表达式
Java Collectors.teeing() 方法
Java 基准测试
Java 文本块
Java 动态CDS
Java ZGC
Java NullPointerException
Java jpackage
Java 密封类
Java 记录
Java 隐藏类
Java instanceof
Java 紧凑数字格式化
Java 垃圾回收
Java JIT 编译器

Java 杂项

Java 递归
Java 正则表达式
Java 序列化
Java 字符串类
Java 进程 API
Java Stream API
Java @Deprecated 注释
Java CompletableFuture API
Java Streams
Java 日期时间 API

基础

Java 主页
Java 概述
Java 历史
Java 功能
Java 与 C++
Java JVM(Java虚拟机)
Java JDK、JRE 和 JVM
Java Hello World 程序
Java 环境设置
Java 基本语法
Java 变量类型
Java 数据类型
Java 类型转换
Java Unicode 系统
Java 基本运算符
Java 注释
Java 用户输入
Java 日期和时间

控制语句

Java 循环控制
Java 决策结构
Java if-else 语句
Java switch 语句
Java for 循环
Java for each 循环
Java while 循环
Java do...while 循环
Java break 语句
Java continue 语句

面向对象编程

Java OOP概念
Java 类和对象
Java 类属性
Java 类方法
Java 方法
Java 变量作用域
Java 构造函数
Java 访问修饰符
Java 继承
Java 聚合
Java 多态
Java 覆盖
Java 方法重载
Java 动态绑定
Java 静态绑定
Java 实例初始化块
Java 抽象
Java 封装
Java 接口
Java 包
Java 内部类
Java 静态类
Java 匿名类
Java 单例类
Java 包装类
Java 枚举类
Java 枚举构造函数
Java 枚举字符串

内置类

Java 数字
Java 布尔值
Java 字符
Java 数组
Java 数学类

文件处理

Java 文件
Java 创建文件
Java 写入文件
Java 读取文件
Java 删除文件
Java 目录操作
Java I/O流

错误和异常

Java 异常
Java Try Catch
Java try-with-resources
Java 多个 Catch
Java 嵌套 try
Java finally
Java 抛出异常
Java 异常传播
Java 内置异常
Java 自定义异常

多线程

Java 多线程
Java 线程生命周期
Java 创建线程
Java 启动线程
Java 加入线程
Java 命名线程
Java 线程调度
Java 线程池
Java 主线程
Java 线程优先级
Java 守护线程
Java 线程组
Java JVM 关闭

同步

Java 线程同步
Java 块同步
Java 静态同步
Java 线程间通信
Java 线程死锁
Java 中断线程
Java 线程控制
Java 可重入锁

网络

Java 网络编程
Java 套接字编程
Java URL 处理
Java URL 类
Java URLConnection 类
Java HttpURLConnection 类
Java Socket 类
Java 泛型

集合

Java 集合框架
Java 集合接口

接口

Java 列表接口
Java 队列接口
Java 映射接口
Java SortedMap 接口
Java 集合(Set)接口
Java SortedSet 接口

数据结构

Java 数据结构
Java 枚举接口

集合算法

Java 迭代器
Java 比较器
Java Comparable 接口

高级

Java 命令行参数
Java Lambda 表达式
Java 发送电子邮件
Java 小应用程序
Java Javadoc
Java 自动装箱和拆箱
Java mismatch() 方法
Java REPL
Java 多版本发布 JAR
Java 私有接口方法
Java 金刚石操作符
Java 多分辨率图像 API
Java 集合的工厂方法
Java 模块系统
Java Nashorn 引擎
Java Optional 类
Java 方法引用
Java 功能接口
Java 默认方法
Java Base64 工具类
Java Switch 表达式
Java Collectors.teeing() 方法
Java 基准测试
Java 文本块
Java 动态CDS
Java ZGC
Java NullPointerException
Java jpackage
Java 密封类
Java 记录
Java 隐藏类
Java instanceof
Java 紧凑数字格式化
Java 垃圾回收
Java JIT 编译器

杂项

Java 递归
Java 正则表达式
Java 序列化
Java 字符串类
Java 进程 API
Java Stream API
Java @Deprecated 注释
Java CompletableFuture API
Java Streams
Java 日期时间 API

Java 异常


上一章 下一章

异常是什么?

异常(或异常事件)是在程序执行期间出现的问题。当异常发生时,程序的正常流程会被中断并且程序/应用会异常终止,这是不建议的情况,因此,这些异常需要被处理。

为什么会出现异常?

异常可能由于多种不同的原因而发生。以下是一些可能出现异常的情形:

  • 用户输入了无效的数据。
  • 需要打开的文件无法找到。
  • 在通信过程中网络连接中断或者 JVM 内存耗尽。

其中一些异常是由用户错误引起的,另一些则是由于编程错误,还有一些则是由于物理资源出现了某种形式的故障。

Java 异常类别

基于以上情况,我们有以下几种异常类别。理解这些可以帮助了解 Java 中的异常处理工作原理。

已检查异常(Checked exceptions)

已检查异常是编译器在编译时检查(通知)的异常,这些也被称为编译时异常。这些异常不能被简单忽略,程序员必须处理(处理)这些异常。

示例:Java 中的已检查异常

例如,如果你在程序中使用 FileReader 类来从文件中读取数据,如果指定的文件不存在,则会发生 FileNotFoundException,编译器提示程序员处理这个异常。

import java.io.File;
import java.io.FileReader;

public class FilenotFound_Demo {

   public static void main(String args[]) {  
      File file = new File("E://file.txt");
      FileReader fr = new FileReader(file); 
   }
}

如果你尝试编译上述程序,你会得到以下异常信息。

C:\>javac FilenotFound_Demo.java
FilenotFound_Demo.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
      FileReader fr = new FileReader(file);
                      ^
1 error

注意 —— 由于 FileReader 类的方法 read() 和 close() 抛出 IOException,你可以看到编译器还通知处理 IOException。

未检查异常(Unchecked exceptions)

未检查异常是在执行时发生的异常。这些也被称作运行时异常。这些包括编程错误,如逻辑错误或不当使用 API。运行时异常在编译时会被忽略。

示例:Java 中的未检查异常

例如,如果你在程序中声明了一个大小为 5 的数组,并试图调用该数组的第 6 个元素,则会引发 ArrayIndexOutOfBoundsException 异常。

public class Unchecked_Demo {
   
   public static void main(String args[]) {
      int num[] = {1, 2, 3, 4};
      System.out.println(num[5]);
   }
}

如果你编译并执行上述程序,你会得到以下异常。

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
 at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)

错误(Errors)

这些不是异常,而是超出用户或程序员控制的问题。错误通常在你的代码中被忽略,因为你很少能对错误做些什么。例如,如果发生栈溢出,就会产生一个错误。在编译时也会被忽略。

Java 异常层次结构

所有的异常类都是 java.lang.Exception 类的子类。Exception 类是 Throwable 类的一个子类。除了 Exception 类之外,还有一个名为 Error 的子类也派生于 Throwable 类。

错误是发生在严重失败的情况下异常条件,这些在 Java 程序中通常不会被处理。错误是用来指示由运行环境生成的错误。例如:JVM 内存不足。通常,程序不能从错误中恢复。

Exception 类有两个主要子类:IOException 类和 RuntimeException 类。

例外1

Java 内置异常列表

以下是最常见的已检查和未检查的 Java 内置异常列表。

Java 异常类方法

以下是 Throwable 类中重要的方法列表。

表格:重要方法及其描述

序号 方法与描述
1 public String getMessage()
返回关于已发生异常的详细消息。此消息在 Throwable 构造函数中初始化。
2 public Throwable getCause()
返回表示为 Throwable 对象的异常原因。
3 public String toString()
返回类名与 getMessage() 的结果的拼接。
4 public void printStackTrace()
将 toString() 的结果以及堆栈跟踪打印到 System.err,即错误输出流。
5 public StackTraceElement [] getStackTrace()
返回一个数组,包含堆栈跟踪上的每个元素。索引 0 的元素代表调用堆栈的顶部,而数组的最后一个元素代表堆栈底部的方法。
6 public Throwable fillInStackTrace()
用当前堆栈跟踪填充此 Throwable 对象的堆栈跟踪,添加到堆栈跟踪中的任何先前信息。

捕捉异常:Java 中的异常处理

一个方法使用 try 和 catch 关键字组合来捕捉异常。try/catch 块放置在可能生成异常的代码周围。位于 try/catch 块中的代码被称为受保护的代码,使用 try/catch 的语法如下所示:

语法

try {
   // 受保护的代码
} catch (ExceptionName e1) {
   // 捕获块
}

可能会抛出异常的代码放在 try 块中。当异常发生时,该异常被相应的 catch 块处理。每个 try 块后面应该紧跟一个 catch 块或 finally 块。

捕获语句涉及声明你要捕获的异常类型。如果受保护的代码中发生了异常,随后的 catch 块(或多个 catch 块)将被检查。如果发生异常的类型列在某个 catch 块中,异常则传递给该 catch 块,如同参数传递到方法参数中一样。

示例:演示异常处理

在下面的例子中,声明了一个具有两个元素的数组。然后代码试图访问数组的第三个元素,这将引发异常。

// 文件名:ExcepTest.java
import java.io.*;

public class ExcepTest {

   public static void main(String args[]) {
      try {
         int a[] = new int[2];
         System.out.println("访问第三个元素:" + a[3]);
      } catch (ArrayIndexOutOfBoundsException e) {
         System.out.println("异常:" + e);
      }
      System.out.println("超出捕获块范围");
   }
}

输出:

异常:java.lang.ArrayIndexOutOfBoundsException: 3
超出捕获块范围

多个捕获块

一个 try 块后面可以跟多个 catch 块。多个 catch 块的语法如下:

语法

try {
   // 受保护的代码
} catch (ExceptionType1 e1) {
   // 捕获块
} catch (ExceptionType2 e2) {
   // 捕获块
} catch (ExceptionType3 e3) {
   // 捕获块
}

前面的语句演示了三个 catch 块,但你可以在一个单一的 try 后面有任意数量的 catch 块。如果受保护的代码中发生了异常,异常将被抛给列表中的第一个 catch 块。如果抛出的异常类型匹配 ExceptionType1,则在那里被捕获。如果不匹配,则异常传递给第二个 catch 语句。这种情况一直持续到异常被捕获或者穿过所有 catch 块,在这种情况下,当前方法停止执行并且异常被抛给调用堆栈上的前一个方法。

示例

下面是展示如何使用多个 try/catch 语句的代码段。

try {
   file = new FileInputStream(fileName);
   x = (byte) file.read();
} catch (IOException i) {
   i.printStackTrace();
   return -1;
} catch (FileNotFoundException f) { // 不正确!
   f.printStackTrace();
   return -1;
}

捕获多种类型的异常

从 Java 7 开始,你可以使用单个 catch 块处理多个异常,这一特性简化了代码。以下是具体做法:

catch (IOException|FileNotFoundException ex) {
   logger.log(ex);
   throw ex;
}

Throws/Throw 关键字

如果一个方法没有处理已检查异常,那么该方法必须使用 throws 关键字声明这个异常。throws 关键字出现在方法签名的末尾。

你可以使用 throw 关键字抛出一个异常,无论是新实例化的还是刚刚捕获的异常。

尝试理解 throws 和 throw 关键字之间的区别,throws 用于推迟处理已检查异常,而 throw 用于显式地引发一个异常。

以下方法声明它抛出一个 RemoteException:

示例

import java.io.*;
public class className {

   public void deposit(double amount) throws RemoteException {
      // 方法实现
      throw new RemoteException();
   }
   // 类的其余部分
}

一个方法可以声明它抛出多个异常,在这种情况下,异常在用逗号分隔的列表中声明。例如,以下方法声明它抛出一个 RemoteException 和一个 InsufficientFundsException。

Java 中的异常

异常是什么?

异常(或异常事件)是在程序执行期间出现的问题。当异常发生时,程序的正常流程会被中断并且程序/应用会异常终止,这是不建议的情况,因此,这些异常需要被处理。

为什么会出现异常?

异常可能由于多种不同的原因而发生。以下是一些可能出现异常的情形:

  • 用户输入了无效的数据。
  • 需要打开的文件无法找到。
  • 在通信过程中网络连接中断或者 JVM 内存耗尽。

其中一些异常是由用户错误引起的,另一些则是由于编程错误,还有一些则是由于物理资源出现了某种形式的故障。

Java 异常类别

基于以上情况,我们有以下几种异常类别。理解这些可以帮助了解 Java 中的异常处理工作原理。

已检查异常(Checked exceptions)

已检查异常是编译器在编译时检查(通知)的异常,这些也被称为编译时异常。这些异常不能被简单忽略,程序员必须处理(处理)这些异常。

示例:Java 中的已检查异常

例如,如果你在程序中使用 FileReader 类来从文件中读取数据,如果指定的文件不存在,则会发生 FileNotFoundException,编译器提示程序员处理这个异常。

import java.io.File;
import java.io.FileReader;

public class FilenotFound_Demo {

   public static void main(String args[]) {  
      File file = new File("E://file.txt");
      FileReader fr = new FileReader(file); 
   }
}

如果你尝试编译上述程序,你会得到以下异常信息。

C:\>javac FilenotFound_Demo.java
FilenotFound_Demo.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
      FileReader fr = new FileReader(file);
                      ^
1 error

注意 —— 由于 FileReader 类的方法 read() 和 close() 抛出 IOException,你可以看到编译器还通知处理 IOException。

未检查异常(Unchecked exceptions)

未检查异常是在执行时发生的异常。这些也被称作运行时异常。这些包括编程错误,如逻辑错误或不当使用 API。运行时异常在编译时会被忽略。

示例:Java 中的未检查异常

例如,如果你在程序中声明了一个大小为 5 的数组,并试图调用该数组的第 6 个元素,则会引发 ArrayIndexOutOfBoundsException 异常。

public class Unchecked_Demo {
   
   public static void main(String args[]) {
      int num[] = {1, 2, 3, 4};
      System.out.println(num[5]);
   }
}

如果你编译并执行上述程序,你会得到以下异常。

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
 at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)

错误(Errors)

这些不是异常,而是超出用户或程序员控制的问题。错误通常在你的代码中被忽略,因为你很少能对错误做些什么。例如,如果发生栈溢出,就会产生一个错误。在编译时也会被忽略。

Java 异常层次结构

所有的异常类都是 java.lang.Exception 类的子类。Exception 类是 Throwable 类的一个子类。除了 Exception 类之外,还有一个名为 Error 的子类也派生于 Throwable 类。

错误是发生在严重失败的情况下异常条件,这些在 Java 程序中通常不会被处理。错误是用来指示由运行环境生成的错误。例如:JVM 内存不足。通常,程序不能从错误中恢复。

Exception 类有两个主要子类:IOException 类和 RuntimeException 类。

Java 内置异常列表

以下是最常见的已检查和未检查的 Java 内置异常列表。

Java 异常类方法

以下是 Throwable 类中重要的方法列表。

表格:重要方法及其描述

序号 方法与描述
1 public String getMessage()
返回关于已发生异常的详细消息。此消息在 Throwable 构造函数中初始化。
2 public Throwable getCause()
返回表示为 Throwable 对象的异常原因。
3 public String toString()
返回类名与 getMessage() 的结果的拼接。
4 public void printStackTrace()
将 toString() 的结果以及堆栈跟踪打印到 System.err,即错误输出流。
5 public StackTraceElement [] getStackTrace()
返回一个数组,包含堆栈跟踪上的每个元素。索引 0 的元素代表调用堆栈的顶部,而数组的最后一个元素代表堆栈底部的方法。
6 public Throwable fillInStackTrace()
用当前堆栈跟踪填充此 Throwable 对象的堆栈跟踪,添加到堆栈跟踪中的任何先前信息。

捕捉异常:Java 中的异常处理

一个方法使用 try 和 catch 关键字组合来捕捉异常。try/catch 块放置在可能生成异常的代码周围。位于 try/catch 块中的代码被称为受保护的代码,使用 try/catch 的语法如下所示:

语法

try {
   // 受保护的代码
} catch (ExceptionName e1) {
   // 捕获块
}

可能会抛出异常的代码放在 try 块中。当异常发生时,该异常被相应的 catch 块处理。每个 try 块后面应该紧跟一个 catch 块或 finally 块。

捕获语句涉及声明你要捕获的异常类型。如果受保护的代码中发生了异常,随后的 catch 块(或多个 catch 块)将被检查。如果发生异常的类型列在某个 catch 块中,异常则传递给该 catch 块,如同参数传递到方法参数中一样。

示例:演示异常处理

在下面的例子中,声明了一个具有两个元素的数组。然后代码试图访问数组的第三个元素,这将引发异常。

// 文件名:ExcepTest.java
import java.io.*;

public class ExcepTest {

   public static void main(String args[]) {
      int a[] = new int[2];
      try {
         System.out.println("访问第三个元素:" + a[3]);
      } catch (ArrayIndexOutOfBoundsException e) {
         System.out.println("异常:" + e);
      } finally {
         a[0] = 6;
         System.out.println("第一个元素值:" + a[0]);
         System.out.println("finally 子句被执行");
      }
   }
}

输出:

异常:java.lang.ArrayIndexOutOfBoundsException: 3
第一个元素值:6
finally 子句被执行

终于块(Finally Block)

finally 块跟随 try 块或 catch 块。无论是否发生异常,finally 块中的代码总是被执行。

使用 finally 块允许你运行任何你希望执行的清理型语句,不管在受保护的代码中发生了什么。

finally 块出现在 catch 块的末尾,具有以下语法:

语法

try {
   // 受保护的代码
} catch (ExceptionType1 e1) {
   // 捕获块
} catch (ExceptionType2 e2) {
   // 捕获块
} catch (ExceptionType3 e3) {
   // 捕获块
} finally {
   // finally 子句总是执行。
}

注意事项

  • catch 子句不能脱离 try 语句存在。
  • 当 try/catch 块存在时,并不一定需要有 finally 子句。
  • try 块不能没有 catch 子句或 finally 子句。
  • 任何代码不能存在于 try, catch, finally 块之间。

使用带有资源的 try 语句(try-with-resources)

通常,当我们使用像流、连接等资源时,我们需要显式地在 finally 块中关闭它们。在下面的程序中,我们使用 FileReader 从文件中读取数据,并且在 finally 块中关闭它。

示例

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadData_Demo {

   public static void main(String args[]) {
      FileReader fr = null;  
      try {
         File file = new File("file.txt");
         fr = new FileReader(file); char [] a = new char[50];
         fr.read(a);   // 将内容读入数组
         for(char c : a)
         System.out.print(c);   // 打印字符
      } catch (IOException e) {
         e.printStackTrace();
      } finally {
         try {
            fr.close();
         } catch (IOException ex) {  
            ex.printStackTrace();
         }
      }
   }
}

try-with-resources 语句,也称为自动资源管理,是 Java 7 中引入的一种新的异常处理机制,它可以自动关闭 try-catch 块中使用的资源。

为了使用这个语句,只需在括号内声明所需的资源,并且创建的资源将在块结束时自动关闭。以下是 try-with-resources 语句的语法:

语法

try(FileReader fr = new FileReader("file path")) {
   // 使用资源
} catch (IOException e) {
   // 捕获块
}

示例

import java.io.FileReader;
import java.io.IOException;

public class Try_withDemo {

   public static void main(String args[]) {
      try(FileReader fr = new FileReader("E://file.txt")) {
         char [] a = new char[50];
         fr.read(a);   // 将内容读入数组
         for(char c : a)
         System.out.print(c);   // 打印字符
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

注意事项

  • 要使用 try-with-resources 语句,类需要实现 AutoCloseable 接口,并且它的 close() 方法会在运行时自动被调用。
  • 你可以在 try-with-resources 语句中声明多个类。
  • 当你在 try-with-resources 语句的 try 块中声明多个类时,这些类会以相反的顺序关闭。
  • 除了括号内的资源声明外,其他一切与正常的 try/catch 块相同。
  • 在 try 块开始之前声明的资源会被实例化。
  • 在 try 块中声明的资源隐式地被声明为 final。

Java 中的自定义异常

你可以在 Java 中创建自己的异常。编写自己的异常类时,请记住以下几点:

  • 所有异常都必须是 Throwable 的子类。
  • 如果你想写一个已检查异常,该异常由处理或声明规则自动强制执行,你需要扩展 Exception 类。
  • 如果你想写一个运行时异常,你需要扩展 RuntimeException 类。

语法

我们可以定义自己的异常类如下:

class MyException extends Exception {
}

你只需要扩展预定义的 Exception 类来创建自己的异常。这些都是已检查异常。下面的 InsufficientFundsException 类是一个扩展 Exception 类的自定义异常,使其成为一个已检查异常。异常类就像其他任何类一样,包含有用的字段和方法。

示例:创建自定义异常

// 文件名 InsufficientFundsException.java
import java.io.*;

public class InsufficientFundsException extends Exception {
   private double amount;
   
   public InsufficientFundsException(double amount) {
      this.amount = amount;
   }
   
   public double getAmount() {
      return amount;
   }
}

为了演示使用我们自定义的异常,下面的 CheckingAccount 类包含一个抛出 InsufficientFundsException 的 withdraw() 方法。

// 文件名 CheckingAccount.java
import java.io.*;

public class CheckingAccount {
   private double balance;
   private int number;
   
   public CheckingAccount(int number) {
      this.number = number;
   }
   
   public void deposit(double amount) {
      balance += amount;
   }
   
   public void withdraw(double amount) throws InsufficientFundsException {
      if(amount <= balance) {
         balance -= amount;
      } else {
         double needs = amount - balance;
         throw new InsufficientFundsException(needs);
      }
   }
   
   public double getBalance() {
      return balance;
   }
   
   public int getNumber() {
      return number;
   }
}

下面的 BankDemo 程序演示了调用 CheckingAccount 的 deposit() 和 withdraw() 方法。

// 文件名 BankDemo.java
public class BankDemo {

   public static void main(String [] args) {
      CheckingAccount c = new CheckingAccount(101);
      System.out.println("存款 $500...");
      c.deposit(500.00);
      
      try {
         System.out.println("\n取款 $100...");
         c.withdraw(100.00);
         System.out.println("\n取款 $600...");
         c.withdraw(600.00);
      } catch (InsufficientFundsException e) {
         System.out.println("对不起,您缺少 $" + e.getAmount());
         e.printStackTrace();
      }
   }
}

编译上述三个文件并运行 BankDemo。这将产生以下结果:

Output

存款 $500...

取款 $100...

取款 $600...
对不起,您缺少 $200.0
InsufficientFundsException
         at CheckingAccount.withdraw(CheckingAccount.java:25)
         at BankDemo.main(BankDemo.java:13)

常见的 Java 异常

在 Java 中,可以定义两类异常和错误:

  • JVM 异常 — 这些是专由 JVM 逻辑上抛出的异常/错误。例子:NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException。
  • 程序性异常 — 这些异常是由应用程序或 API 编程者显式抛出的。例子:IllegalArgumentException、IllegalStateException。
上一章 下一章
阅读号二维码

关注阅读号

联系二维码

联系我们

© 2024 Yoagoa. All rights reserved.

粤ICP备18007391号

站点地图