异常处理就好比穿底裤,穿了不能轻易的给别人看,更不能不穿。否则浪潮褪去,沙滩上裸奔的人就是你。
异常是一种错误的事件,它在程序执行过程中发生,影响了程序的正常流程。当一个方法遇到异常情况时,它通常会创建一个包含异常信息的对象,然后将控制权交给程序的某个地方,这个地方可以是异常处理代码或者调用栈的其他部分。Java中的异常处理机制是基于传统的C++异常处理机制的,它强制程序员捕获可能出现的异常并进行处理。这使得程序的可靠性得以提高,因为异常情况不再被忽略,而是被明确地处理。
异常处理的主要目标是使程序更具可读性和可维护性,因为异常处理代码通常集中在一起,而不是分散在程序的各个部分。通过使用异常,程序员可以更容易地理解和维护代码,因为异常处理的代码与正常的业务逻辑相分离。
在 Java 中,异常是指在程序执行期间发生的意外情况,它可能导致程序终止或产生不确定的结果。异常分为两种类型:已检查异常(checked exceptions)
和未检查异常(unchecked exceptions)
。
已检查异常通常表示程序无法预测的外部条件,例如文件不存在或网络连接中断。
未检查异常通常表示程序内部错误,例如空指针引用或数组越界。在任何情况下,异常都提供了一种将错误处理代码从正常的业务逻辑中分离出来的方法,以确保程序的健壮性。
受检异常(checked exceptions)和未受检异常(unchecked exceptions)。
这类异常是在编译时检查的,必须在代码中进行处理,否则程序无法通过编译。常见的例子包括 IOException
和 SQLException
。可以使用 try-catch
块来捕获并处理这些异常,或者在方法签名中使用 throws
关键字声明方法可能抛出的异常。
try {
// 一些可能抛出异常的代码
} catch (IOException e) {
// 处理 IOException
} catch (SQLException e) {
// 处理 SQLException
}
这类异常通常是由程序错误引起的,是在运行时检测的。常见的例子包括 NullPointerException
和 ArrayIndexOutOfBoundsException
。通常,最好通过编码和设计来避免这些异常的发生。但如果确信无法避免,可以使用try-catch
来处理。
try {
// 一些可能抛出异常的代码
} catch (NullPointerException e) {
// 处理 NullPointerException
} catch (ArrayIndexOutOfBoundsException e) {
// 处理 ArrayIndexOutOfBoundsException
}
无论异常是否被捕获,finally
块中的代码都将被执行。这通常用于确保资源的释放,比如关闭文件或网络连接。
try {
// 一些可能抛出异常的代码
} catch (Exception e) {
// 处理异常
} finally {
// 无论是否发生异常,都会执行这里的代码
}
这就是 Java 异常处理的基本概念。理解异常机制并合理处理异常有助于编写更稳定、可靠的 Java 代码。
Java 异常类层次结构图主要分为两个分支:Throwable
作为根类,分为 Error
和 Exception
两个主要的子类。
代表了系统级别的错误,通常是由虚拟机报告的。程序通常无法捕获这类错误,因为它们表示了严重的问题,无法通过程序来恢复。
OutOfMemoryError
:内存耗尽StackOverflowError
:栈溢出代表了程序运行期间的异常情况,分为受检异常和未受检异常。
受检异常(Checked Exceptions)
需要在代码中显式处理或者在方法签名中声明可能抛出的异常。
IOException
:输入输出异常SQLException
:数据库访问异常未受检异常(Unchecked Exceptions)
通常是由程序错误引起的,不需要显式处理。
RuntimeException
:运行时异常的基类NullPointerException
:空指针异常ArrayIndexOutOfBoundsException
:数组下标越界异常ArithmeticException
:算术异常IllegalArgumentException
:非法参数异常ClassCastException
:类转换异常这只是异常类层次结构的一个概览,实际上,Java 提供了众多的异常类以覆盖各种可能的异常情况。理解这个层次结构对于编写健壮的 Java 代码至关重要。
try
关键字用于定义一个包含可能抛出异常的代码块。在这个代码块中,可以放置可能引发异常的语句。
try {
// 可能引发异常的代码
} catch (Exception e) {
// 处理异常的代码
} finally {
// 无论是否发生异常都会执行的代码
}
catch
关键字用于捕获并处理异常。在 catch
块中,可以指定要捕获的异常类型,并编写处理异常的代码。
try {
// 可能引发异常的代码
} catch (ExceptionType e) {
// 处理特定类型的异常的代码
}
finally
关键字用于定义一个代码块,其中的代码无论是否发生异常都会被执行。通常用于清理资源或确保某些代码总是执行。
try {
// 可能引发异常的代码
} catch (Exception e) {
// 处理异常的代码
} finally {
// 无论是否发生异常都会执行的代码
}
throw
关键字用于手动抛出异常。可以使用它来抛出特定类型的异常对象。
throw new MyException("This is a user exception");
throws
关键字用于在方法签名中声明可能抛出的异常。它告诉调用方可能需要处理的异常类型。
void myMethod() throws MyException {
// 方法体
}
这些关键字一起构成了Java中的异常处理机制,通过它们,可以更好地管理和处理程序中的异常情况。
throw 关键字:
当使用 throw
关键字时,在代码中明确指定某个异常对象的抛出。这通常发生在方法内部,表示在特定条件下手动引发异常。下面是一个简单的例子:
package com.example.demo.exception;
public class ExampleThrow {
public static void main(String[] args) {
try {
validateAge(15);
} catch (CustomException e) {
System.out.println("Caught exception: " + e.getMessage());
}
}
static void validateAge(int age) throws CustomException {
if (age < 18) {
throw new CustomException("Age must be 18 or older");
} else {
System.out.println("Valid age: " + age);
}
}
}
class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
在这个例子中,validateAge
方法接受一个年龄参数,如果年龄小于 18,则使用 throw
关键字手动抛出一个 CustomException
异常。在 main
方法中,我们调用了 validateAge(15)
,由于年龄小于 18,所以会抛出异常,然后我们在 catch
块中捕获并处理了这个异常。
throws 关键字:
void myMethod() throws MyException { // 方法体 }
现在,让我们看看 throws 关键字的使用。throws 通常用于在方法签名中声明可能抛出的异常类型。下面是一个例子:
package com.example.demo.exception;
public class ExampleThrows {
public static void main(String[] args) {
try {
processInput(25);
processInput(-5);
} catch (CustomException e) {
System.out.println("Caught exception: " + e.getMessage());
}
}
static void processInput(int input) throws CustomException {
if (input < 0) {
throw new CustomException("Input cannot be negative");
} else {
System.out.println("Processed input: " + input);
}
}
}
class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
在这个例子中,processInput
方法声明了可能抛出 CustomException
异常。在 main
方法中,我们调用了 processInput(25)
,因为输入是正数,所以不会抛出异常。如果我们调用 processInput(-5)
,则由于输入是负数,会抛出 CustomException
异常。
总结一下:
throw
用于在代码中手动抛出异常。throws
用于在方法签名中声明可能抛出的异常类型,以便调用方知道需要处理哪些异常。Exception
或其子类。public class CustomException extends Exception {
public CustomException() {
super();
}
public CustomException(String message) {
super(message);
}
}
示例:
public class TryCatchExample {
public static void main(String[] args) {
try {
int result = divide(10, 0);
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
}
}
static int divide(int numerator, int denominator) {
return numerator / denominator;
}
}
解释:
try
块中,我们尝试执行除法操作。ArithmeticException
。catch
块中,我们捕获并处理 ArithmeticException
,打印错误消息。示例:
public class TryCatchFinallyExample {
public static void main(String[] args) {
try {
int result = divide(10, 0);
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
} finally {
System.out.println("This block always executes.");
}
}
static int divide(int numerator, int denominator) {
return numerator / denominator;
}
}
解释:
finally
块。finally
块中的代码都会执行。示例:
public class TryFinallyExample {
public static void main(String[] args) {
try {
// 一些可能抛出异常的代码
} finally {
System.out.println("This block always executes.");
}
}
}
解释:
catch
块,仅有 try
块和 finally
块。finally
块中的代码都会执行。try-with-resources
是 Java 7 引入的一个语法糖,用于更方便地管理资源,如文件、网络连接等,而无需显式地在代码中添加资源关闭的语句。这个语法确保在 try
块结束时,所有在括号中声明的资源都会被关闭,即使在 try
块中发生异常。
示例:
package com.example.demo.exception;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
public class TryWithResourcesExample {
public static void main(String[] args) {
// 使用 try-with-resources 读取文件内容
try (FileReader fileReader = new FileReader("E:\\example.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader)) {
String line;
// 逐行读取文件内容
while ((line = bufferedReader.readLine()) != null) {
System.out.println("Read from file: " + line);
}
} catch (IOException e) {
System.out.println("Error reading file: " + e.getMessage());
}
}
}
try-with-resources
来读取文件内容。FileReader
和 BufferedReader
都是实现了 AutoCloseable
接口的资源。try
括号内声明了这两个资源,无需手动关闭,它们会在 try
块结束时自动关闭。AutoCloseable
或 Closeable
接口。try-with-resources
语句结束时,会按照声明的顺序逆序关闭资源,即先声明的资源先关闭。异常的基本概念:
异常处理的优势:
捕获和处理异常:
try-catch
块可以捕获并处理异常,防止它们传播到程序的上层。异常的层次结构:
finally块的作用:
finally
块中的代码无论是否发生异常,都会被执行。finally
块通常用于确保资源的释放或清理操作。自定义异常:
异常与错误处理的哲学观点:
IOException:
FileNotFoundException:
ParseException:
ClassNotFoundException:
SQLException:
InterruptedException:
FileNotFoundException:
ParseException:
ClassNotFoundException:
NullPointerException:
ArrayIndexOutOfBoundsException:
ArithmeticException:
IllegalArgumentException:
IllegalStateException:
NumberFormatException:
ClassCastException:
NullPointerException:
除了未检查异常和已检查异常,Java还包括一些其他类型的异常。这些异常通常是作为Error
类的子类,表示更加严重且通常是不可恢复的问题。以下是一些其他常见的异常:
OutOfMemoryError:
StackOverflowError:
NoClassDefFoundError:
LinkageError:
AssertionError:
ExceptionInInitializerError:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。