正如“人无完人”一样,程序也不是完美的,它总会存在这样那样的问题,如果忽视它,可能就会造成程序的终止,甚至是系统的崩溃。异常是指程序在执行过程中,出现的非正常情况,可能由程序员错误、系统错误或用户输入错误引起。
Java 使用面向对象的方式来表示和处理这些错误,JAVA中的异常继承自 java.lang.Throwable 类,主要分为两类:
Java 提供了结构化的异常处理机制,可以通过 try-catch-finally 语句来捕获和处理异常,避免程序崩溃:
下面汇总一些常见异常类型及处理方法:
//说明:当试图将对象强制转换为不兼容的类型时抛出此异常。
Object x = new Integer(0);
System.out.println((String)x); // 会抛出 ClassCastException
处理方法:
//说明:在类型转换之前使用 instanceof 关键字检查对象是否属于某个特定类型。。
if (x instanceof String) {
String s = (String) x;
} else {
// 处理类型不匹配的情况
}
//说明:当尝试通过类的名字加载类,但找不到类时抛出此异常。
try {
Class.forName("com.example.UnknownClass");
} catch (ClassNotFoundException e) {
e.printStackTrace(); // 会抛出 ClassNotFoundException
}
处理方法:确保引用的类存在于正确的位置,并且类路径设置正确。如果使用外部库或框架,确保将相关的jar文件添加到类路径中。
//说明:当出现异常的算术操作时,例如除以零。
int result = 10 / 0; // 会抛出 ArithmeticException
处理方法:
//说明:在进行除法或取模运算时,要确保除数不为零,可以使用条件语句预先检查除数是否为零。
if (b != 0) {
int result = a / b;
// 进一步处理
}
//说明:当试图访问数组中不存在的索引时抛出此异常。
int[] arr = new int[5];
int value = arr[10]; // 会抛出 ArrayIndexOutOfBoundsException
处理方法:
//说明:确保访问数组时,索引值在有效范围内。要注意Java数组的索引从0开始,因此最大索引是数组长度减1。
if (index >= 0 && index < arr.length) {
int element = arr[index];
// 进一步处理
}
5.ArrayStoreException (数组存储异常)
//说明:当试图将错误类型的对象存储到对象数组中时抛出此异常。
Object[] array = new String[5];
array[0] = 1; // 会抛出 ArrayStoreException
处理方法:
//说明:当试图将错误类型的对象存储到对象数组中时抛出此异常。
Object[] array = new String[5];
try {
array[0] = 1; // 这个地方抛出 ArrayStoreException
} catch (ArrayStoreException e) {
System.out.println("类型不匹配");
}
6.SQLException (操作数据库异常)
//说明:当操作数据库时,发生访问数据库错误或违反 SQL 语法时抛出此异常。
try {
Connection conn = DriverManager.getConnection(url, username, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users");
// 处理结果集
} catch (SQLException e) {
e.printStackTrace();
}
处理方法:在进行数据库操作时,应注意处理可能发生的SQLException异常。可以使用try-catch语句块捕获异常,并根据具体情况进行错误处理,如打印错误信息、关闭资源或进行事务回滚。
7.NullPointerException (空指针异常)
//说明:当应用程序试图在空对象上调用方法或访问空对象的字段时抛出此异常。
String str = null;
str.length(); // 会抛出 NullPointerException
处理方法:
//说明:在使用对象之前检查是否为空 (null),避免调用空对象的方法或属性,使用 Optional 类来避免空指针异常。
String str = null;
if (str != null) {
System.out.println(str.length());
} else {
System.out.println("对象为空");
}
8.NoSuchFieldException (字段未找到异常)
//说明:当类不存在指定字段时抛出此异常。
try {
Field field = String.class.getField("unknownField");
} catch (NoSuchFieldException e) {
e.printStackTrace(); // 会抛出 NoSuchFieldException
}
处理方法:
//说明:捕获异常并处理,如提供备用字段或默认行为。
try {
Field field = String.class.getField("unknownField");
} catch (NoSuchFieldException e) {
System.out.println("字段未找到");
}
9.NoSuchMethodException (方法未找到异常)
//说明:当方法在类中不存在时抛出此异常。
try {
Method method = String.class.getMethod("unknownMethod");
} catch (NoSuchMethodException e) {
e.printStackTrace(); // 会抛出 NoSuchMethodException
}
处理方法:
//说明:捕获异常并提供备用处理逻辑。
try {
Method method = String.class.getMethod("unknownMethod");
} catch (NoSuchMethodException e) {
System.out.println("方法未找到");
}
10.NumberFormatException (数字格式化异常)
//说明:当应用程序试图将字符串转换为数字,但该字符串无法解析为有效数字时抛出此异常。
String numberStr = "ABC123";
int number = Integer.parseInt(numberStr);
处理方法:
//说明:在进行字符串转换为数字的操作之前,确保字符串仅包含有效的数字字符。可以使用正则表达式或合适的校验方法来验证字符串是否为有效的数字。
String numberStr = "123";
if (numberStr.matches("\\d+")) {
int number = Integer.parseInt(numberStr);
// 进一步处理
}
11.NegativeArraySizeException (数组大小为负异常)
//说明:当试图创建大小为负的数组时抛出此异常。
int[] array = new int[-5]; // 会抛出 NegativeArraySizeException
处理方法:
//说明:捕获异常并提示数组大小错误。
try {
int[] array = new int[-5];
} catch (NegativeArraySizeException e) {
System.out.println("数组大小不能为负");
}
12.StringIndexOutOfBoundsException (字符串下标越界异常)
//说明:当访问字符串中不存在的索引时抛出此异常。
String str = "hello";
char ch = str.charAt(10); // 会抛出 StringIndexOutOfBoundsException
处理方法:
//说明:捕获异常并提示字符串越界。
String str = "hello";
try {
char ch = str.charAt(10);
} catch (StringIndexOutOfBoundsException e) {
System.out.println("字符串索引越界");
}
13.IOException (输入输出异常)
//说明:与 I/O 操作相关的异常,当读写文件或网络时出现错误抛出此异常。
FileReader fr = new FileReader("non_existent_file.txt"); // 会抛出 IOException
处理方法:
//说明:捕获异常并记录错误日志。
try {
FileReader fr = new FileReader("non_existent_file.txt");
} catch (IOException e) {
System.out.println("文件读取错误");
}
14.IllegalAccessException (非法访问异常)
//说明:当试图访问类或方法时,没有访问权限时抛出此异常。
class Test {
private void privateMethod() {}
}
try {
Method method = Test.class.getDeclaredMethod("privateMethod");
method.invoke(new Test()); // 会抛出 IllegalAccessException
} catch (IllegalAccessException e) {
e.printStackTrace();
}
处理方法:
//说明:捕获异常并进行提示。
try {
Method method = Test.class.getDeclaredMethod("privateMethod");
method.invoke(new Test());
} catch (IllegalAccessException e) {
System.out.println("非法访问");
}
15.InstantiationException (实例化异常)
//说明:如尝试实例化抽象类抛出此异常。
abstract class Animal {
public abstract void sound();
}
public class Test {
public static void main(String[] args) {
try {
Animal animal = Animal.class.newInstance(); // 会抛出 InstantiationException
} catch (InstantiationException | IllegalAccessException e) {
System.out.println("无法实例化抽象类: " + e);
}
}
}
处理方法:
//说明:可以通过创建具体子类来避免这个异常。
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Bark");
}
}
public class Test {
public static void main(String[] args) {
try {
Animal animal = Dog.class.newInstance(); // 实例化具体的子类
animal.sound(); // 输出 "Bark"
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
16.EOFException (文件结束异常)
//说明:当程序试图读取文件的末尾时抛出此异常。
FileInputStream fis = new FileInputStream("somefile.txt");
while (fis.read() != -1) {
// 读取文件直到 EOF
}
处理方法:
//说明:捕获 EOFException,并提供适当的逻辑来处理文件读取完成的情况。
try {
FileInputStream fis = new FileInputStream("file.txt");
while (fis.read() != -1) {
// 读取文件内容
}
} catch (EOFException e) {
System.out.println("已到达文件末尾");
} catch (IOException e) {
e.printStackTrace();
}
17.FileNotFoundException (文件未找到异常)
//说明:当试图打开文件的文件名无效时抛出此异常。
FileReader fr = new FileReader("non_existent_file.txt"); // 会抛出 FileNotFoundException
处理方法:
//说明:在尝试打开文件之前,先检查文件是否存在,或者捕获 FileNotFoundException 并提示用户文件路径是否正确。
File file = new File("non_existent_file.txt");
if (file.exists()) {
FileReader fr = new FileReader(file);
} else {
System.out.println("文件未找到");
}