Java-异常的处理方式
try-catch-finall
真正的将异常给处理掉了
throws
的方式只是将异常抛给了方法的调用者,并没有真正的将异常处理掉
1.概念
- 异常的处理:
“抛”
:程序在正常执行的过程中,一旦出现异常,就会在异常代码除生成一个对应的异常类的对象,并将此对象抛出,一旦抛出对象以后,其后的代码不在执行“抓”
:可以理解为异常的处理方式:
try-catch-finall
try{
可能出现异常的代码
}catch(异常类型1 变量名1){
}catch(异常类型2 变量名2){
}catch(异常类型3 变量名3){
}
...
// finally 是可选的,不一定要有
finally{
一定会执行的代码
}
- finally是可选的;
- 使用try将可能出现异常的代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应的异常类的对象,根据此对象的类型,去catch中进行匹配;
- 一旦try中的异常对象匹配到某一个catch时,就进行catch中进行异常的处理,一旦处理完成就跳出当前的try catch结构(在没有写finally的情况下)。继续执行其后面的代码;
- catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓。catch中的异常类型如果要满足子父类的关系,则要求子类一定声明在父类的上面,否则,报错;
- 常用的异常对象的处理方式:
e.getMessage()、e.printStackTrace()
- 在try结构中声明的变量,在出了try结构之后就无法调用,如果需要在try结构外面使用,可以在try之前声明和初始化变量。
- 使用
try catch finally
处理编译时异常,使得程序在编译时就不报错,但是在运行时仍可能报错,相当于我们使用try catch finally
将一个可能出现的异常,延迟到运行时出现。 - 开发中,由于运行时异常比较常见,使用我们通常不针对运行时异常编写
try catch finally
,而针对编译时异常,我们一定要考虑异常的处理。 - finally是可选的,表示声明的代码一定会执行,即时catch中还有异常,或者在try中有return语句,finally声明的语句都会执行。
package p8exception;
import org.junit.Test;
public class Finally {
@Test
public void test2() {
Finally a = new Finally();
System.out.println(a.method());
}
public int method() {
try {
int[] arr = new int[10];
System.out.println(arr[10]);
return 1;
}catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
System.out.println("异常处理了");
return 2;
}finally {
System.out.println("我一定会执行");
// 值也一定返回
return 3;
}
}
}
- 像数据库连接、输入输出流、网络编程Socket等资源,JVM是不能自动回收的,我们需要自己手动的进行资源的释放,此时资源的释放,就需要声明在finally中。
package p8exception;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Finally {
@Test
public void test7() {
FileInputStream fils = null;
try {
File file = new File("hello.txt");
fils = new FileInputStream(file);
int data = fils.read();
while (data != -1) {
System.out.print((char)data);
}
fils.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
// try catch操作可以相互嵌套
try {
// 避免空指针异常
if (fils != null) {
fils.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
throws
-
throws+ 异常类型
写在方法的声明处,指明此方法执行时,可以会抛出的异常类型,一旦当方法体执行时,出现异常,仍会在异常代码除生成一个异常对象,此对象满足throws后异常的类型是,就会被抛出。异常代码后续的代码,就不再执行。
2.try-catch-finall
package p8exception;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionTest1 {
// 类型转换异常 NumberFormatException
@Test
public void test4() {
String str = "abc";
try {
int num = Integer.parseInt(str);
System.out.println("hello 1");
} catch (NumberFormatException e) {
// System.out.println(e.getMessage());
e.printStackTrace();
} catch (NullPointerException e) {
System.out.println("空指针异常");
}
System.out.println("hello 2");
}
//FileNotFoundException 编译时异常
@Test
public void test7() {
try {
File file = new File("hello.txt");
FileInputStream fils = new FileInputStream(file);
int data = fils.read();
while (data != -1) {
System.out.print(data);
}
fils.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.throws + 异常类型
package p8exception;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionTest3 {
// main方法(再抛就给JVM了)应该处理子方法抛上来的异常
public static void main(String[] args) {
try {
method2();
}catch (Exception e) {
e.printStackTrace();
}
}
// method2 把错误向上抛出异常给 main方法,main方法就不能在抛了
public static void method2() throws IOException {
method1();
}
// method1 把错误向上抛出异常给 method2
public static void method1() throws IOException {
File file = new File("hello1.txt");
FileInputStream fils = new FileInputStream(file);
int data = fils.read();
while (data != -1) {
System.out.print(data);
data = fils.read();
}
fils.close();
}
}
4.开发中如何选择try-catch-finall
还是throws + 异常类型
- 如果父类中被重写的方法中没有
throws
方式处理异常,则子类重写的方法也不能使用thorws,
意味着如果子类重写的方法中有异常,必须使用try-catch-finall
- 执行的方法a中先后有调用了另外的几个方法,这个几个方法时递进关系执行的,我们建议这几个方法 使用
throws
的方式处理,而执行的方法a可以考虑使用try-catch-finall
的方式进行处理。