Java - 异常(二)- 异常处理的方式1:捕获异常(try-catch-finally)

目录

第六章 异常处理

🐶6.1 异常处理概述

🐶6.2 方式1:捕获异常(try-catch-finally)

6.2.1 try-catch-finally基本格式

6.2.2 示例代码

6.2.3 整体执行过程:

6.2.4 开发体会

6.2.5 finally

6.2.6 异常处理的体会

❓面试题: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的区别

  1. final代表最终,当final用来修饰类时,代表这个类为最终类,不可以被继承。当final用来修饰变量时,代表这个变量为常量,不可以被修改;当final用来修饰方法时,该方法不可以被重写。

  2. finally用于抛异常,finally代码块内语句无论是否发生异常,都会执行。通常用于一些流的关闭。

  3. finalize方法用于垃圾回收。一般情况下不需要我们实现finalize,当对象被回收的时候需要释放一些资源,比如socket链接,在对象初始化时创建,整个生命周期内有效,那么需要实现finalize方法,关闭这个链接。

但是当finalize方法后,并不意味着gc会立即回收该对象,所以有可能等真正调用的时候,对象又不需要回收了,然后到了真正要回收的时候,因为之前调用过一次,这次又不会调用了,产生问题。所以,不推荐使用finalize方法。

  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java异常处理是编程中很重要的一部分,其中try-catch语句是常用的异常捕获机制。当代码块中可能会抛出异常时,可以使用try-catch捕获并处理异常,避免程序崩溃。 在try块中,我们编写可能会出现异常的代码。当某个异常被抛出时,程序会立即跳转到对应的catch块中,执行catch块中的代码。catch块中的异常参数会接收到被抛出的异常对象,我们可以通过该参数对异常进行处理。 在catch块中,我们可以根据不同的异常类型采取不同的处理方式。比如,可以输出异常信息、记录日志、进行重试操作等。如果catch块成功处理了异常,程序会继续执行try-catch之后的代码;如果catch块没有成功处理异常异常将继续向上抛出。 另外,可以在try-catch语句中添加多个catch块,以便对不同类型的异常进行处理。catch块的顺序很重要,应该根据具体的异常类型进行有针对性的处理。通常,将子类异常放在前面的catch块,将父类异常放在后面的catch块。 最后,如果在try块中没有出现异常,catch块中的代码将不会执行。但是,可以使用finally块来确保一定会执行的代码,比如资源的释放操作。 总之,通过使用try-catch语句,我们可以有效地捕获并处理异常,增加程序的健壮性和稳定性。对于很多场景来说,我们不希望因为一个小的异常导致整个程序崩溃,因此合理地使用try-catch是非常重要的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值