Java中的异常处理:解释说明

Java中的异常处理是您作为Java开发人员将学习的最重要的概念之一!本教程将帮助您正确理解和实现异常处理。

每个计算机程序都有其特定的执行流程。如果发生了一些“意外”情况,这将导致程序的正常流程被打乱。

例如,将任何数值除以零或访问数组中不存在的索引。这种现象在编程中被称为“异常”。

简单来说,异常是您没有预料到会发生的事情,但它可能发生,您需要处理它。

为什么会发生异常?

关键在于“可能性”。有很多事情可能出错。网络状态、用户交互、无效的输入等都可能导致异常。重要的是如何处理您认为会在某个时候以某种方式发生的这些异常。

JVM的异常处理

当Java程序内发生异常时,将创建一个对象来描述异常,包括异常的类型和发生异常时程序的状态。然后将此对象传递给JVM。JVM尝试查找一个方法或函数来处理异常。它会遍历能够潜在处理异常的方法列表。

图片来源: Oracle

一旦找到适当的方法来处理异常,它将异常交给该方法处理,但如果找不到适当的方法,它将调用默认的异常处理方法来终止程序。

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的信息。

类似文章