Java - 异常(二)- 异常处理的方式1:捕获异常(try-catch-finally)
目录
🐶6.2 方式1:捕获异常(try-catch-finally)
?面试题:final,finally,finalize的区别
第六章 异常处理
Java异常处理的五个关键字:try、catch、finally、throw、throws
🐶6.1 异常处理概述
在编写程序时,经常要在可能出现错误的地方加上检测的代码,如进行x/y运算时,要检测分母为0,数据为空,输入的不是数据而是字符等。过多的if-else分支会导致程序的代码加长、臃肿,可读性差,程序员需要花很大的精力“堵漏洞”。因此采用异常处理机制。
Java异常处理
Java采用的异常处理机制,是将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序简洁、优雅,并易于维护。
Java异常处理的方式:
方式一:try-catch-finally
方式二:throws + 异常类型
🐶6.2 方式1:捕获异常(try-catch-finally)
Java提供了异常处理的抓抛模型。
-
前面提到,Java程序的执行过程中如出现异常,会生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出(throw)异常。
-
如果一个方法内抛出异常,该异常对象会被抛给调用者方法中处理。如果异常没有在调用者方法中处理,它继续被抛给这个调用方法的上层方法。这个过程将一直继续下去,直到异常被处理。这一过程称为捕获(catch)异常。
-
如果一个异常回到main()方法,并且main()也不处理,则程序运行终止。
6.2.1 try-catch-finally基本格式
捕获异常语法如下:
try{
...... //可能产生异常的代码
}
catch( 异常类型1 e ){
...... //当产生异常类型1型异常时的处置措施
}
catch( 异常类型2 e ){
...... //当产生异常类型2型异常时的处置措施
}
finally{
...... //无论是否发生异常,都无条件执行的语句
}
6.2.2 示例代码
import java.sql.SQLOutput;
import java.util.Date;
import java.util.InputMismatchException;
import java.util.Scanner;
// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
public static void main(String[] args) throws Exception{
try{
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
System.out.println(num);
}catch(InputMismatchException e){
System.out.println("出现了InputMismatchException的异常");
}
System.out.println("异常处理结束,代码继续执行");
}
}
结果:
6.2.3 整体执行过程:
当某段代码可能发生异常,不管这个异常是编译时异常(受检异常)还是运行时异常(非受检异常),我们都可以使用try块将它括起来,并在try块下面编写catch分支尝试捕获对应的异常对象。
-
如果在程序运行时,try块中的代码没有发生异常,那么catch所有的分支都不执行。
-
如果在程序运行时,try块中的代码发生了异常,根据异常对象的类型,将从上到下选择第一个匹配的catch分支执行。此时try中发生异常的语句下面的代码将不执行,而整个try...catch之后的代码可以继续运行。
-
如果在程序运行时,try块中的代码发生了异常,但是所有catch分支都无法匹配(捕获)这个异常,那么JVM将会终止当前方法的执行,并把异常对象“抛”给调用者。如果调用者不处理,程序就挂了。
2、try
-
捕获异常的第一步是用try{…}语句块选定捕获异常的范围,将可能出现异常的业务逻辑代码放在try语句块中。
3、catch (Exceptiontype e)
-
catch分支,分为两个部分,catch()中编写异常类型和异常参数名,{}中编写如果发生了这个异常,要做什么处理的代码。
-
如果明确知道产生的是何种异常,可以用该异常类作为catch的参数;也可以用其父类作为catch的参数。
比如:可以用ArithmeticException类作为参数的地方,就可以用RuntimeException类作为参数,或者用所有异常的父类Exception类作为参数。但不能是与ArithmeticException类无关的异常,如NullPointerException(catch中的语句将不会执行)。
-
每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。
-
如果有多个catch分支,并且多个异常类型有父子类关系,必须保证小的子异常类型在上,大的父异常类型在下。否则,报错。
?catch中常用异常处理的方式
-
自己编写输出的语句
-
public String getMessage():获取异常的描述信息,返回字符串
-
public void printStackTrace():打印异常的跟踪栈信息并输出到控制台。包含了异常的类型、异常的原因、还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace()。
6.2.4 开发体会
1. 对于运行时异常
开发中,通常就不进行显示的处理了
一旦在程序执行中,出现了运行时异常,那么就根据异常的提示信息修改代码即可。
2. 对于编译时异常
一定要处理,否则编译不通过
6.2.5 finally
1. 概念
我们将一定要被执行的代码声明在finally结构中
更深刻的理解:无论try中或catch中是否存在仍未被处理的异常,无论try中或catch中是否return语句等,finally中声明的语句都一定要被执行。
2. 代码示例
🧀代码示例1:
import java.sql.SQLOutput;
import java.util.Date;
import java.util.InputMismatchException;
import java.util.Scanner;
// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
public static void main(String[] args) throws Exception{
int result=test("a");
System.out.println(result);
}
public static int test(String str){
try{
Integer.parseInt(str);
return 1;
}catch (NumberFormatException e){
return -1;
}finally {
System.out.println("test结束");
}
}
}
结果:
🧀代码示例2:
import java.sql.SQLOutput;
import java.util.Date;
import java.util.InputMismatchException;
import java.util.Scanner;
// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
public static void main(String[] args) throws Exception{
int result=test("a");
System.out.println(result);
}
public static int test(String str){
try{
Integer.parseInt(str);
return 1;
}catch (NumberFormatException e){
return -1;
}finally {
System.out.println("test结束");
return 0;
}
}
}
?结果:
?
?🧀代码示例3:
public class Main {
public static void main(String[] args) throws Exception{
int result=test(10);
System.out.println(result);
}
public static int test(int num){
try{
return num;
}catch (NumberFormatException e){
return num--;
}finally {
System.out.println("test结束");
return ++num;
}
}
}
结果:
3. finally使用及举例
- 因为异常会引发程序跳转,从而会导致有些语句执行不到。而程序中有一些特定的代码无论异常是否发生,都需要执行。什么时候的代码必须最终执行?
??????????当我们在try语句块中打开了一些物理资源(磁盘文件/网络连接/数据库连接等),我们都得在使用完之后,最终关闭打开的资源。
??????????这样的代码通常就会放到finally块中。所以,我们通常讲一定要执行的代码声明在finally中。
-
唯一的例外,使用System.exit(0)来终止当前正在运行的Java虚拟机。
-
finally语句和catch语句是可选的,但finally不能单独使用。
try{
}finally{
}
6.2.6 异常处理的体会
-
前面使用的异常都是RuntimeException类或是它的子类,这些类的异常的特点是:即使没有try和catch捕获,java自己也能捕获,并且编译通过(但运行时会发生异常使得程序运行终止)。所以,对于这类异常,可以不做处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。
-
如果抛出的异常是IOException等类型的非运行时异常,则必须捕获,否则编译错误。也就是说,我们必须处理编译时异常,将异常进行捕捉,转化为运行时异常。
?面试题:final,finally,finalize的区别
-
final代表最终,当final用来修饰类时,代表这个类为最终类,不可以被继承。当final用来修饰变量时,代表这个变量为常量,不可以被修改;当final用来修饰方法时,该方法不可以被重写。
-
finally用于抛异常,finally代码块内语句无论是否发生异常,都会执行。通常用于一些流的关闭。
-
finalize方法用于垃圾回收。一般情况下不需要我们实现finalize,当对象被回收的时候需要释放一些资源,比如socket链接,在对象初始化时创建,整个生命周期内有效,那么需要实现finalize方法,关闭这个链接。
但是当finalize方法后,并不意味着gc会立即回收该对象,所以有可能等真正调用的时候,对象又不需要回收了,然后到了真正要回收的时候,因为之前调用过一次,这次又不会调用了,产生问题。所以,不推荐使用finalize方法。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!