相关内容来自腾讯元宝, 作者也属于入门,仅做参考
异常就是程序运行时可能出现的一些错误,例如数组下标越界、空指针异常或算数异常。
也可以是我们自己认为的异常,可以直接抛出(需要我们继承异常类,来实现一个自定义的异常)
Error 和 Exception
Throwable (可抛出对象)
├── Error (错误) // 严重问题,不应捕获
│ ├── VirtualMachineError
│ ├── LinkageError
│ └── ...
└── Exception (异常) // 可恢复的问题
├── RuntimeException (运行时异常) // unchecked
└── 其他Exception (检查型异常) // checked
error:
- 不可恢复:通常表示严重问题
- 不应捕获:程序无法从中恢复
- JVM级别:通常与JVM或系统资源相关
- 非检查型:不强制捕获或声明
--
exception:
- 必须处理(try-catch 或 throws)
- 编译时检查
- 通常表示可恢复的问题 `

我们一般是不捕获处理Error类的异常的,这代表不正确的代码,应该避免
而Exception 代表着例外,需要捕获处理,让程序进行下去.可以返回给前端,让其提醒用户规避
如何处理呢?
捕获异常:使用try-catch块来捕获并处理可能发生的异常。
java
try {
// 可能抛出编译时异常的代码
} catch (IOException e) {
// 处理异常
}
声明抛出异常:在方法签名中使用throws关键字声明该方法可能抛出的异常。
java
public void readFile(String path) throws IOException {
// 可能抛出IOException的代码
}
内置的常用异常
java
public class RuntimeExceptionExample {
public void demonstrateRuntimeExceptions() {
// 1. NullPointerException
try {
String str = null;
int length = str.length(); // 抛出NullPointerException
} catch (NullPointerException e) {
System.out.println("空指针异常: " + e.getMessage());
}
// 2. IllegalArgumentException
try {
setAge(-1);
} catch (IllegalArgumentException e) {
System.out.println("非法参数异常: " + e.getMessage());
}
// 3. IndexOutOfBoundsException
try {
int[] array = {1, 2, 3};
int value = array[5]; // 数组越界
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组越界异常: " + e.getMessage());
}
// 4. ArithmeticException
try {
int result = 10 / 0; // 除以零
} catch (ArithmeticException e) {
System.out.println("算术异常: " + e.getMessage());
}
// 5. ClassCastException
try {
Object obj = "字符串";
Integer num = (Integer) obj; // 类型转换错误
} catch (ClassCastException e) {
System.out.println("类型转换异常: " + e.getMessage());
}
}
private void setAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数: " + age);
}
// 设置年龄逻辑
}
}
throw
发现最后一句似乎跟其他不一样
java
throw new IllegalArgumentException("年龄不能为负数: " + age);
throw抛出的情况
- 代码自动抛出
- 手动 throw new Exception("")
这是由我们手动抛出的, 而且没有捕获,那说明程序运行到这个异常
throw语句会立即终止当前方法的执行 ,其后的代码不会继续运行
而使用 try{} catch()的格式, 我们手动捕获并让其继续运行下面的代码
java
public class WithTryCatch {
public void processOrder(int age) {
try {
if (age < 0) {
throw new IllegalArgumentException("年龄无效: " + age);
}
System.out.println("验证通过,继续处理...");
} catch (IllegalArgumentException e) {
// 捕获异常,但不重新抛出
System.out.println("捕获到异常: " + e.getMessage());
// 记录日志,但不终止程序
log.error("年龄验证失败", e);
}
// ✅ 这里的代码会继续执行!
System.out.println("继续执行后续逻辑...");
cleanup();
}
public static void main(String[] args) {
WithTryCatch demo = new WithTryCatch();
demo.processOrder(-5);
System.out.println("程序继续运行"); // ✅ 会执行
}
}
java
public class WithoutTryCatch {
public void processOrder(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄无效: " + age);
}
// 如果 age < 0,这里的代码永远不会执行!
System.out.println("处理订单...");
saveToDatabase();
sendNotification();
}
public static void main(String[] args) {
WithoutTryCatch demo = new WithoutTryCatch();
demo.processOrder(-5); // 抛出异常,程序终止
System.out.println("这行代码不会执行"); // ❌ 不会执行
}
}
总结一下:
有些代码会自动抛出某些异常, 我们可以用try{} catch() {} 来捕获处理,
也可以手动抛出异常,当然也可以用try{}catch(){} 来捕获处理.
如果不处理,异常后面的代码不会继续运行,一般这就和我们的逻辑相违背了,所有一般需要处理,除非这串代码的目的就是抛出个异常
学习到这里 就有个疑问了
方法后面跟着throws 和 方法内使用 throw 有什么区别和分别有什么用处呢?
throws
throws关键字是 Java 中用于声明方法可能抛出异常的重要机制。它的主要作用是在方法签名中明确声明该方法可能抛出的检查型异常。
我们来看thows的典型的几个例子
1.强制异常处理
java
// 方法声明时使用 throws
public void readFile(String path) throws IOException {
// 可能抛出 IOException
FileReader file = new FileReader(path);
}
// 调用者必须处理或继续声明
public void processFile() {
try {
readFile("data.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
2.异常传播
java
public void methodA() throws IOException {
methodB(); // 不立即处理,向上层传递
}
public void methodB() throws IOException {
// 可能抛出 IOException
}
throws 主要还是预先申明 方法里面可能会抛出的异常
throws关键字的核心价值在于:
- 提高代码可读性:明确方法可能出现的错误情况
- 强制错误处理:确保调用者正确处理可能的异常
- 支持异常传播:允许异常在调用链中向上传递
- 增强类型安全:编译器可检查异常处理逻辑
正确使用 throws是编写健壮、可维护 Java 代码的关键技能之一。