1. Java异常类层次结构
Throwable
|
------------------
| |
Error Exception
|
-----------------------
| |
RuntimeException 非运行时异常
Throwable类作为所有异常类的基类,分为两个子类:Error和Exception。Error类表示Java虚拟机内部的错误和资源耗尽等严重问题,通常不应该被程序捕获和处理,因为这些错误无法恢复,例如OutOfMemoryError和StackOverflowError等。
Exception类则表示程序中可能会出现的一般性异常,它又分为两类:非运行时异常和运行时异常。
2. 运行时异常是什么?
运行时异常(RuntimeException)是指在程序运行时可能会抛出的异常。它们属于非检查异常(Unchecked Exception),程序中可以不显式地声明或捕获这些异常,但是如果出现这些异常,程序就会终止运行。
运行时异常通常是由程序逻辑错误、算术错误、空指针引用等原因引起的,这些错误可以通过代码检查和测试来避免,但在代码中不需要显式地处理。例如:
ArithmeticException:算术运算异常,例如除数为 0;
NullPointerException:空指针异常,例如访问一个空对象的成员;
ArrayIndexOutOfBoundsException:数组下标越界异常,例如访问数组时下标超出了数组的范围;
ClassCastException:类型转换异常,例如将一个对象强制转换为不相容的类型等。
3. 非运行时异常是什么?
运行时异常(RuntimeException)是指在程序运行时可能会抛出的异常。它们属于非检查异常(Unchecked Exception),程序中可以不显式地声明或捕获这些异常,但是如果出现这些异常,程序就会终止运行。
运行时异常通常是由程序逻辑错误、算术错误、空指针引用等原因引起的,这些错误可以通过代码检查和测试来避免,但在代码中不需要显式地处理。例如:
ArithmeticException:算术运算异常,例如除数为 0;
NullPointerException:空指针异常,例如访问一个空对象的成员;
ArrayIndexOutOfBoundsException:数组下标越界异常,例如访问数组时下标超出了数组的范围;
ClassCastException:类型转换异常,例如将一个对象强制转换为不相容的类型;
IllegalArgumentException:非法参数异常,例如传递给方法的参数值不符合要求等。
4. throw和throws的区别?
throw 和 throws 都是 Java 中用于异常处理的关键字,它们的作用不同:
- throw关键字(异常的抛出):用于抛出异常对象,它通常用于方法内部,当程序运行到某个异常情况时,可以手动抛出一个异常对象,并且会立即终止当前方法的执行。例如:
public void divide(int a, int b) {
if (b == 0) {
throw new IllegalArgumentException("除数不能为0");
}
int result = a / b;
System.out.println("结果为:" + result);
}
- throws关键字(异常的声明):用于声明方法可能会抛出哪些异常,它通常用于方法的定义部分,用于告诉调用者方法可能会抛出哪些异常,调用者可以根据这些信息来决定如何处理异常。例如:
public void readFile(String fileName) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
// 读取文件内容
reader.close();
}
当一个方法声明了 throws 异常时,在调用该方法时,调用者需要使用 try-catch 语句来处理可能会抛出的异常,或者将这些异常再次抛出。
例如,在调用 readFile() 方法时,可以使用 try-catch 语句来处理 FileNotFoundException 和 IOException 异常,代码如下:
public static void main(String[] args) {
String fileName = "example.txt";
try {
readFile(fileName);
} catch (FileNotFoundException e) {
System.out.println("文件不存在:" + fileName);
e.printStackTrace();
} catch (IOException e) {
System.out.println("读取文件出错:" + fileName);
e.printStackTrace();
}
}
在上述代码中,首先定义了一个字符串变量 fileName,然后在 try 代码块中调用了 readFile() 方法。如果 readFile() 方法抛出了 FileNotFoundException 异常,就会进入第一个 catch 代码块中处理该异常;如果抛出了 IOException 异常,就会进入第二个 catch 代码块中处理该异常。
另外,如果调用者不想处理异常,也可以将异常再次抛出,例如:
public static void main(String[] args) throws FileNotFoundException, IOException {
String fileName = "example.txt";
readFile(fileName);
}