1、异常的两种处理方式
1、异常上抛
在方法声明的位置上,使用throws
关键字,抛给上一级
谁调用我,我就抛给谁,抛给上一级。
2、异常捕捉
使用try..catch语句
进行异常的捕捉
这件事发生了,谁也不知,因为我给抓住了。
举例:
我是某集团的一个销售员,因为我的失误,导致公司损失了1000块钱。"损失1000块"这可以看做一个异常发生了。我有两种处理方式。
- 第一种方式:我把这件事告诉我的领导。【异常上抛】
- 第二种方式:我把自己的掏腰包把这个钱补上。【异常的捕捉】
同样的异常发生之后,如果选择上抛,抛给了调用者,调用者需要对这个异常继续处理,那么调用者处理这个异常同样有两种处理方式。
注意:
Java中异常发生之后如果一直上抛,最终抛给了main方法,main方法继续向上抛,抛给了调用者JVM,JVM知道这个异常的发生,只有只有一个结果。终止java程序的执行。
2、运行时异常编写程序时可以不处理
public class ExceptionTest01 {
public static void main(String[] args) {
int a = 10;
int b = 0;
int c=a/b;
/*
程序执行到此处发生了ArithmeticException异常
底层new一个ArithmeticException异常对象
然后抛出了,由于是main方法调用了c=a/b
所以这个异常ArithmeticException抛给main方法
main方法没有处理,将这个异常自动抛给JVM
JVM最终终止程序的执行
ArithmeticException 继承 RuntimeException,属于运行时异常。
在编写程序阶段不需要对这种异常进行预先的处理。
*/
System. out.println(a + "/”+ b + "="+ c);
//这里的HelloWorld没有输出,没有执行。
System.out.println("Hello World!");//
}
}
3、方法声明上使用throws
以下代码报错的原因是什么?
因为doSome()方法声明位置上使用了:throws ClassNotFoundException
而ClassNotFoundException是编译时异常。必须编写代码时处理,没有处理编译器报错。
public class ExceptionText1 {
public static void main(String[] args) {
//main方法中调用doSome()方法
//因为doSome()方法声明位置上有:throws ClassNotFoundException
//我们在调用doSome()方法的时候必须对这种异常进行预先的处理。
//如果不处理,编译器就报错
//报错信息: 未报告的异常错误java.lang.ClassNotFoundException
doSome();
}
/**
* doSome方法在方法声明的位置上使用了:throws ClassNotFoundException
* 这个代码表示doSome()方法在执行过程中,有可能会出现ClassNotFoundException异常。
* 叫做类没找到异常。这个异常直接父类是: Exception,所以ClassNotFoundException属于编译异常。
* @throws ClassNotFoundException
*/
public static void doSome() throws ClassNotFoundException{
System.out.println("doSome!!!");
}
}
4、异常处理的具体方式
第一种处理方式:在方法声明的位置上继续使用:throws,来完成异常的继续上抛。抛给调用者
上抛类似于推卸责任。(继续把异常传递给调用者)
这种处理异常的态度:上报
public class ExceptionText1 {
public static void main(String[] args) throws ClassNotFoundException {
doSome();
}
public static void doSome() throws ClassNotFoundException{
System.out.println("doSome!!!");
}
}
第二种方式:try ... catch
进行异常捕捉
捕捉等于把异常拦下了,异常真正的解决了。(调用者不知道的)
public class ExceptionText1 {
public static void main(String[] args) throws ClassNotFoundException {
try {
//尝试
doSome();
}catch (ClassNotFoundException e){
//catch是捕捉异常之后走的分支
e.printStackTrace;
}
}
public static void doSome() throws ClassNotFoundException{
System.out.println("doSome!!!");
}
}
一般不建议在main方法上使用throws,因为这个异常如果真正发生了,一定会抛给JVM。JVM只有终止。一般采用try...catch
进行捕捉。
5、异常捕捉和上报的联合使用
import java.io.FileInputStream;
public class ExceptionText2 {
public static void main(String[] args) {
System.out.println("main begin ");
m1();
System.out.println("main over");
}
private static void m1(){
System.out.println("m1 begin");
m2();
System.out.println("m1 over");
}
private static void m2(){
System.out.println("m2 begin");
m3();
System.out.println("m3 over");
}
private static void m3(){
//调用SUN jdk中某个类的构造方法
//这个类是IO流的
//创建一个输入流对象,该流指向一个文件。
new FileInputStream("C:\\Users\\Administrator\\Desktop\\Java自学\\学习.txt");
}
}
编译报错的原因:
- 第一:这里调用了一个构造方法:
FileInputStream(String name)
- 第二:这个构造方法的声明位置上有:throws FileNotFoundException
- 第三:通过类的继承结构看到:FileNotFoundException父类是IOException,IOException的父类是Exception。
最终得知,FileNotFoundException是编译时异常。编译时异常要求程序员编写阶段必须对它进行处理,不处理编译器就报错
进行异常处理后
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ExceptionText2 {
public static void main(String[] args) {
System.out.println("main begin ");
m1();
System.out.println("main over");
}
private static void m1(){
System.out.println("m1 begin");
try {
m2();
} catch (FileNotFoundException e) {
//这个分支中可以使用e引用,e引用保存的内存地址是new出来异常对象的内存地址
//catch是捕捉异常之后走的分支
System.out.println("文件不存在,可能路径错误,也可能文件被删除了!");
}
System.out.println("m1 over");
}
//也可以 throws Exception
private static void m2() throws FileNotFoundException {
System.out.println("m2 begin");
//编译器报错的原因是:m3()方法声明位置上有:throws FileNotFoundException
//我们这里调用m3()没有对异常进行预处理,所以编译报错
m3();
System.out.println("m3 over");
}
private static void m3() throws FileNotFoundException {
//调用SUN jdk中某个类的构造方法
//这个类是IO流的
//创建一个输入流对象,该流指向一个文件。
new FileInputStream("C:\\Users\\Administrator\\Desktop\\Java自学\\学习.txt");
}
}
上抛异常也可以 throws Exception
注意:只要异常没有捕捉,采用上报的方式,此方法的后续代码不会执行。
另外需要注意,try语句块中的某一行出现异常,该行后面的代码不会执行。
6、上报和捕捉怎么选择?
- 如果希望调用者来处理,选择throws上报。
- 其他情况可以使用捕捉的方式