异常总结。
1.异常相关简介
异常是java提供的一种识别和响应错误的一致性机制。
从上图可以看出,所有的异常都是由Throwable继承而来的,它是所有异常的祖先。
Throwable有两个子类,Error和Exception。
- Error是错误,编译错误和系统错误都是通过error抛出的,这个错误一般发生在虚拟机本身,或者在虚拟机试图执行任务的时候,比如:系统崩溃、内存不足、堆栈溢出等,编译器不会对这类错误进行检测,java的应用程序也不会对其进行捕获,这类错误一旦发生,程序直接终止。
- Exception又分为Checked Exception和RuntimeException。
- Checked Exception是指受查异常,除了运行异常以外都是被检查异常,比如IOException。java编译器会检查它,此类异常,要么通过throws进行声明抛出,要么通过try-catch进行捕获处理,否则不能通过编译。被检查异常通常是可以恢复的。
- 而RuntimeException是运行时异常,是指那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。编译器不会检查RuntimeException异常。这种异常是运行时发生,无法预先捕捉处理的。如果代码会产生RuntimeException异常,则需要通过修改代码进行避免。
常见的运行时异常:
- 除数为0之类的算术异常ArithmeticException
- 数组越界IndexOutOfBoundsException
- 类文件未找到异常 ClassNotFoundException
- 空指针异常NullPointerException
- 操作数据库异常SQLException
2.怎么处理异常
Java异常机制用到的几个关键字:try、catch、finally、throw、throws。
其中:try-catch,try用来监听,将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。catch用来捕获try代码块中的异常。
finally语句块总是会被执行,用来释放之前获取的资源,所以无论发不发生异常,finally都会执行。finally块执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
throw用来抛出异常,throws用在方法签名中,用于声明该方法可能抛出的异常。
public class Main {
public static void main(String[] args) {
try {
} catch (Exception e) {
}finally{
}
}
}
第二种方法是……直接抛出去,不处理。
虽然有点粗暴,但是有些异常我们没办法处理,只能抛出去,让能解决的人去解决(谁调用谁解决= =。
方法:method declaration的时候加上throws
public class Test{
//受检查异常的抛出,调用的时候需要try-catch处理异常/抛出
private static void throwException() throws Exception{
throw new Exception("Exception");
}
//运行时异常的抛出,调用时不会让你处理异常
private static void throwRuntimeException(){
throw new RuntimeException("RuntimeException");
}
}
可以好几个catch来分开处理不同的异常。
try {
//doing something
} catch (Exception1 e) {
// handle the first type exception
System.out.println("Exception1 happened")
} catch (Exception2 f){
// handle the first type exception
System.out.println("Exception2 happened")
}
一个exception发生之后,如果是Exception1类型的,就会被第一个handle,如果不是Exception1类型的就会接着往下找catch,如果是Exception2类型的,就会被第二个catch块handle。
在网上找到一个很有意思的:
//m1抛出了一个异常
void m1 throws FileNotFoundException(){
//大概是想读一些文件,又不想考虑如果文件找不到咋整。(甩锅)
}
//m2调用了m1,相当于从m1手里接到了这个异常,自己不处理,继续往外甩。
void m2 throws FileNotFoundException(){
m1();//想用m1方法,m1声明如果想用我就要考虑文件找不到的情况。
//但是m2依然不想考虑文件找不到咋整。
}
该博主给的一个综合的例子:
import java.io.File;
import java.io.FileReader;
import java.io.FileNotFoundException;
public class ReadFileTest {
public static void main(String args[]) {
getFile1();
System.out.println("=============");
try{
// 因为getFile2又把exception甩出来了,所以main方法得处理它。
getFile2();
}catch(FileNotFoundException e){
System.out.println("Exception handled in main");
}
}
//getFile1选择了自己处理,不麻烦调用它的方法
public static void getFile1() {
try{
File file = new File("file.txt");
FileReader fr = new FileReader(file);
}catch(FileNotFoundException e){
System.out.println("Exception handled in getfile1");
}
}
//getFile2选择了不处理,继续throws
public static void getFile2() throws FileNotFoundException{
File file = new File("file.txt");
FileReader fr = new FileReader(file);
}
}
运行结果:
Exception handled in getfile1
=============
Exception handled in main
= =一般来讲,所有的exception到了main方法这里都应该已经被解决了。不过好像main方法也可以不解决往外抛出异常……(我凑!
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!