Java中的异常处理:解释说明
Java中的异常处理是您作为Java开发人员将学习的最重要的概念之一!本教程将帮助您正确理解和实现异常处理。
每个计算机程序都有其特定的执行流程。如果发生了一些“意外”情况,这将导致程序的正常流程被打乱。
例如,将任何数值除以零或访问数组中不存在的索引。这种现象在编程中被称为“异常”。
简单来说,异常是您没有预料到会发生的事情,但它可能发生,您需要处理它。
为什么会发生异常?
关键在于“可能性”。有很多事情可能出错。网络状态、用户交互、无效的输入等都可能导致异常。重要的是如何处理您认为会在某个时候以某种方式发生的这些异常。
JVM的异常处理
当Java程序内发生异常时,将创建一个对象来描述异常,包括异常的类型和发生异常时程序的状态。然后将此对象传递给JVM。JVM尝试查找一个方法或函数来处理异常。它会遍历能够潜在处理异常的方法列表。
一旦找到适当的方法来处理异常,它将异常交给该方法处理,但如果找不到适当的方法,它将调用默认的异常处理方法来终止程序。
Java中的异常类型
Java中的异常有两种类型:
Checked:这些类型的异常在编译时由编译器捕获。Java中的一些已检查异常包括IOException和SQLException。
Unchecked:编译器在编译时不知道这些异常,因为它们在运行时才显现出来。它们在代码执行时进行验证。未经检查的异常包括ArrayIndexOutOfBoundsException和IllegalStateException。
处理异常的方法
以下是您可以处理或抛出异常的一些方式:
- try… catch块
- throw/throws关键字
#1. try… catch块
try-catch块用于运行一段代码,在代码中存在异常可能性。try块和catch块是两个独立的代码块,当try块无法正常执行时,catch块将运行。
try {
// 正常的代码
} catch(Exception e) {
// 处理异常的代码
}
还有一个finally块,您可以使用它来执行一些代码,无论是否发生异常。无论如何,此块中的代码都将运行。
try {
// 正常的代码
} catch(Exception e) {
// 处理异常的代码
} finally {
// 一些代码
}
#2. throw和throws关键字
throw关键字用于显式地创建一个异常。如果您知道在特定条件下一定会发生异常,可以使用throw关键字。
public static void occur() {
// 条件
throw new ArithmeticException();
}
public static void main(String[] args) {
try {
occur();
} catch(Exception e) {
// 处理
}
}
您可以使用throws关键字来声明在给定方法中将发生的多个异常。
“`java
public class Main {
public static void main(String[] args) {
try {
occur();
} catch(Exception1 e) {
//…
} catch(Exception2 e) {
//…
} catch(Exception3 e) {
//…
}
}
}
public static void occur() throws Exception1, Exception2, Exception3 {
// conditions which throw different exceptions
}
“`
Java中的一些常见异常
#1. IOException
如果输入/输出过程出现问题,就会发生IOException异常。通常情况下,当您尝试访问文件及其内容,但文件不存在或读取文件内容时出现问题时,会发生此异常。
“`java
import java.io.FileNotFoundException;
import java.io.FileReader;
public class Main {
public static void main(String[] args) {
try {
FileReader file = new FileReader(“hello.txt”);
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
}
}
}
“`
#2. ArrayIndexOutOfBoundsException
数组是一种数据结构,它存储相同数据类型的值,并且每个值都有一个索引,索引从0开始,最大为(n-1),其中n是数组中存在的值的总数。您可以通过指定索引和引用数组的变量名称来访问元素:
“`java
array[index]
“`
现在,如果您尝试访问索引小于0或大于(n-1)的元素,则会发生异常,因为该特定索引处没有元素。这种类型的异常称为ArrayIndexOutOfBoundsException,它在运行时发生。
“`java
public class Main {
public static void main(String[] args) {
try {
int[] arr = {34, 1, 78, 3, 5};
int element = arr[7];
} catch (Exception e) {
System.out.println(e);
}
}
}
“`
#3. ClassCastException
当您尝试将父类的对象强制转换为其子类的类型时,会发生此类型的异常。如果您尝试将对象与与其不兼容的类进行强制类型转换,也会出现此异常。
“`java
class A {
public void display() {
System.out.println(“This is class A”);
}
}
class B extends A {
public void display() {
System.out.println(“This is class B which is a subclass of A”);
}
}
class C extends B {
public void display() {
System.out.println(“This is class C which is a subclass of B”);
}
}
public class Main {
public static void main(String[] args) {
try {
A objA = new A();
B objB = (B) new A();
} catch (Exception e) {
System.out.println(e);
}
}
}
“`
以上代码将抛出ClassCastException,因为我们试图将父类的对象强制转换为其子类的类型。
#4. IllegalArgumentException
当方法或函数接收到无效参数时,可以抛出IllegalArgumentException。例如,假设您正在创建一个计算正方形周长的方法。
在向用户请求正方形的一边长度时,如果得到负值,则可以抛出此异常,因为正方形的一边不能为负。
“`java
public class Main {
public static int perimeter(int length) {
if(length < 0) {
throw new IllegalArgumentException("不允许负值!");
}
return 4 * length;
}
public static void main(String[] args) {
try {
System.out.println(perimeter(-5));
} catch (Exception e) {
System.out.println(e);
}
}
}
“`
#5. IllegalStateException
当您在不应调用方法或函数的时间调用它时,会出现IllegalStateException。例如,如果您在已经启动的线程上调用start方法,那么Java会在运行时抛出此异常。
class AThread extends Thread {
public void run() {
System.out.println("这是一个线程!");
}
}
public class Main {
public static void main(String[] args) {
try {
AThread t = new AThread();
t.start();
t.start();
} catch (Exception e) {
System.out.println(e);
}
}
}
#6. NullPointerException
当您尝试访问空对象或指向空值的变量的属性时,会出现NullPointerException。Null是Java中的一个特殊值,表示未将任何值分配给引用变量。
public class Main {
public static void main(String[] args) {
try {
String num = null;
System.out.println(num.length());
} catch (Exception e) {
System.out.println(e);
}
}
}
#7. NumberFormatException
当您尝试将格式不正确的字符串转换为数字时,会出现NumberFormatException。例如,如果您尝试将“null”或“twenty”转换为数字,那么Java会抛出此异常。
public class Main {
public static void main(String[] args) {
try {
int num = Integer.parseInt("12,389");
System.out.println(num);
} catch (Exception e) {
System.out.println(e);
}
}
}
结论
处理异常很重要,因为它们可能会在程序的流程中创建不必要的中断。请注意,异常与错误不同,因为异常应该被处理,而错误无法处理。相反,它们应该被解决或修复。您可以通过阅读这些online Java courses来了解更多关于Java的信息。