章节六、1-异常---编译时会被检测的

一、异常其实就是将问题封装成对象并抛给调用者,异常的出现是为了提高程序的健壮性而将问题描述出来。

java分两个时期,一个叫编译时期,一个叫运行时期,编译时期就是说检查语法错误,也就是源代码有没有写错,如果源代码没写错,生成的.class文件在运行时期出错,这些情况就叫异常。

二、新建两个类,类名为ExceptionsDemo和Account,使用抛出异常的方式来处理异常。

1、在Account这个类中写一个“取钱”的功能

package introduction8;

/*导入包为
 * import java.sql.Connection;
 * 将Connection改为*后,这样就能一次性将sql这个包中的所有类
*/
import java.sql.Connection;
import java.sql.DriverManager;

public class Accout {
/*    在取钱之前,程序要访问数据库,提供账号信息、余额进行运算,然后判断能不能取出钱,
 *    因此需要先写一个能抛出异常,显示异常的功能,
 *     因为要建立一个数据库链接,使用mysql为例
*/    
    public Connection getConn() {
    //Connection为引用型变量,默认值为空,用于与特定数据库进行连接,
    //他是一个接口,我们需要用到Connection链接
        Connection conn = null;
    //定义连接数据库需要用到的参数
        /*因为使用mysql数据库,所以使用jdbc,表示java数据库连接,
         * 是一种用于执行sql语句的java api,jdbc是java数据库的标准,
         * 提供了一种让java程序连接到数据库的机制,如果要使用jdbc连接到数据库,
         * 必须要使用jdbc驱动程序。
         * (本机还未安装数据库,此处目的是为了演示异常,所以运行时会报异常)
         */
        String url = "jdbc:mysql://localhost:3306/";
        String user = "user";
        String password = "code";
    //Connection是一个静态方法,所以能够直接调用,创建数据库连接
        conn = DriverManager.getConnection(url, user, password);
        return conn;
    }
    public void withdraw(int money) {
        
    }

}

在eclipse中conn = DriverManager.getConnection(url, user, password);代码报错,

这里会报异常是因为Connection接口中有检查异常的机制,所以此处报出了sql异常

2、因为在getConn方法中有异常所以,在这个方法上要有throws声明出来,不然编译会失败,声明的目的是为了让调用这个getConn方法的人去处理,如果调用者也不处理的话,编译还是会失败的,在eclipse中鼠标移动到报错的代码上,会给出上图中两次解决方式(throws抛出异常,try/catch捕获并处理异常),这里选择第一种,直接抛出异常,让调用者自己解决。

3、选择抛出异常后在其它方法中调用,直接调用时会报异常,这就是前面提到的,如果调用者不处理的话,编译还是会报错。然后继续给调用的方法声明抛出异常。

4、在ExceptionsDemo类中调用

package introduction8;

/*
 * 运行时会发生的问题分两类:
 * 1、exception异常:
 * 这种异常是可处理的,java虚拟机是用来解释并执行java程序的应用软件,
 * 这种是异常直接从java虚拟机发生的,是java虚拟机在运行过程中发生的问题,
 * 并告诉给使用者,对异常可以进行针对性处理。
 * exception异常分两种:
 * a、编译时检查的异常,先检查语法的问题,语法都对的情况下再检查语法的安全问题。
 * 对于编译时被检查的异常,功能如果有问题,当功能中又未声明的话,就会报错并且不会让程序执行通过。
 * b、运行时异常,运行时异常编译器是不检查
 * 如果代码中有零做为除数,编译时是不会检查该异常的,运行时才会报错,也就是说除数为零,代码的语法
 * 和功能是没有问题的,只不过传的参数有问题。另外就是数值角标越界的情况,例如数值的长度为3,
 * 角标就是0、1、2这3个数,想访问角标为3的元素,编译时不会报错,运行时报错,因为3这个元素根本不存在。
 * 2、Error错误:
 * Error发生是不处理的,error是由系统底层发生的,底层告诉了java虚拟机的,java虚拟机告诉使用者,
 * 例如内存溢出,一旦发生error了,必须修改代码,对异常本身不做针对性处理。
 */

//因为用的IDE集成开发环境,都是可以检查编译时异常,异常的部分会先红色波浪线和红叉图标
public class ExceptionsDemo {

    public static void main(String[] args) {
        
        Accout acc = new Accout();
        acc.withdraw(100);
    }

}

调用后传参仍然报异常:

继续选择声明异常,点击运行,控制台提示异常

三、使用try/catch捕获异常

package introduction8;

import java.sql.SQLException;

/*
 * 运行时会发生的问题分两类:
 * 1、exception异常:
 * 这种异常是可处理的,java虚拟机是用来解释并执行java程序的应用软件,
 * 这种是异常直接从java虚拟机发生的,是java虚拟机在运行过程中发生的问题,
 * 并告诉给使用者,对异常可以进行针对性处理。
 * exception异常分两种:
 * a、编译时检查的异常,先检查语法的问题,语法都对的情况下再检查语法的安全问题。
 * 对于编译时被检查的异常,功能如果有问题,当功能中又未声明的话,就会报错并且不会让程序执行通过。
 * b、运行时异常,运行时异常编译器是不检查
 * 如果代码中有零做为除数,编译时是不会检查该异常的,运行时才会报错,也就是说除数为零,代码的语法
 * 和功能是没有问题的,只不过传的参数有问题。另外就是数值角标越界的情况,例如数值的长度为3,
 * 角标就是0、1、2这3个数,想访问角标为3的元素,编译时不会报错,运行时报错,因为3这个元素根本不存在。
 * 2、Error错误:
 * Error发生是不处理的,error是由系统底层发生的,底层告诉了java虚拟机的,java虚拟机告诉使用者,
 * 例如内存溢出,一旦发生error了,必须修改代码,对异常本身不做针对性处理。
 */

//因为用的IDE集成开发环境,都是可以检查编译时异常,异常的部分会先红色波浪线和红叉图标
public class ExceptionsDemo {

    public static void main(String[] args){
        
        Accout acc = new Accout();
        try {
        /*把可能出现异常的代码反正try/catch这个大括号里面,
         * 如果try里面的语句有异常,就回去执行catch里面的语句
         */
            acc.withdraw(100);
        } catch (SQLException e) {
        //将异常信息封装成对象并打印
            e.printStackTrace();
        }
    }

}

运行后的结果:

如果想自定义只打印错误信息:

四、catch不能离开try单独使用。

try语句可以没有catch,当try语句不能单独执行,如果没有catch就必须要与finally一起使用。

五、finally{}放在finally中的语句一定会被执行

六、try是如何工作的?

1、在try中添加如下两行代码,以便于我们能直观的看到try是如何运行的

结果:

直接跳过打印“执行withdraw”这条命令语句,执行catch和finally中的语句,这是因为try中有异常

2、注释未处理前报异常的代码

点击执行:

跳过了catch中的语句,只执行了try和finally中的语句,这是因为try中没有异常

7、try与finally一起使用,没有catch

这是在不一定要处理异常,但是有资源需要释放的情况下使用。

注释掉catch,然后运行

运行成功:

finally语句块中可以放释放资源的语句,例如断开数据库连接,有时候程序出现异常,资源是来不及释放的,而如果把资源放在finally中,就可以得到释放,因为finally中的语句是肯定会被执行的。

猜你喜欢

转载自www.cnblogs.com/luohuasheng/p/9641268.html