java学习笔记(3):异常

      要想写出一个好的系统,异常是绕不开的一个结。所谓天有不测风云,人有旦夕祸福。一个系统运转的时候总是“多灾多难”的,特别是真实的用户,往往不会按照程序设计者的思路出牌。如果没有异常的处理,程序的健壮性基本为零,用户体验极差,这样的程序是使用不了的。

一、异常的分类

       java中的异常都继承自Throwable,而需要程序员处理的只有Exception,我们不需要去管Error那部分。Exception又分为RuntimeException(运行时异常)和CheckedException,后者不做处理,在编译时就会抛出。所以往往出问题的就是编程是不易发现的,但是又跟业务息息相关的RuntimeException。

      

如何应对呢?

       我们先从最基础的开始说起。

 try{
            //...业务实现
        }catch (SubException1 e1){
            //...异常处理模块1
        }catch (SubException2 e2){
            //...异常处理模块2
        }
        //...其他异常处理模块
        finally {
            //...回收资源,除非try,catch模块中有退出虚拟机的方法,否则finally一定会执行
        }

       这是最普通的异常处理方式try...catch...finally...,逐个catch异常,最后回收资源。注意的一点是异常父类要写在异常子类下面。

       还有一种特殊的写法,java7的自动关闭资源的try语句。

        FileInputStream fis = null;
        try{
            fis = new FileInputStream("test.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (fis != null){
                fis.close();
            }
        }

       在java7之前finally中的代码是不得不写的,java7之后改变了这种形式

       try(    //声明初始化两个可关闭的资源
               //try语句会自动关闭这两个资源
               BufferedReader br = new BufferedReader(new FileReader("test.txt"));
               PrintStream ps = new PrintStream(new FileOutputStream("test.txt"))
       ){
           System.out.println(br.readLine());
           System.out.println("test opening test.txt");
       }

       try后面加上加上小括号,括号里面可以声明,初始化一个或者多个必须在程序结束时显式关闭的资源(比如数据库连接,网络连接等)。这些资源必须实现AutoCloseable或Closeable接口,也就是要实现close()方法。

二、空指针异常

       空指针异常(NullPointerException)是最常见的RuntimeException。一般而言在参数前面加个判断就可以解决了。

        if (list != null && list.size() > 0) {
            //TODO
        }
     

三、自定义异常

    一般是以下四种方式

public class MyException extends Exception {
    //无参数
    public MyException(){
        super();
    }

    //指定信息
    public MyException(String msg){
        super(msg);
    }
    
    //指定原因和信息
    public MyException(String msg,Throwable casue){
        super(msg,casue);
    }
    
    //指定原因
    public MyException(Throwable cause){
        super(cause);
    }
}
抛出异常
public class ExceptionTest {
    public void getException(int a) {
        try {
            if (a > 0){
                throw new MyException("a is bigger than zero");
            }
        }catch (MyException e){
            //TODO 
        }
    }
}

在使用的过程中,我们的异常要处理之后向上抛出,有些可能需要集中处理然后展示给用户看。

改动下代码:

public class ExceptionTest {
    public void getException(int a) throws MyException{
        try {
            if (a > 0){
                throw new MyException("a is bigger than zero");
            }
        }catch (MyException e){
            throw new MyException("a大于零");
        }
    }
}

测试

public class ExceptionDriver {
    public static void main(String[] args) {
        ExceptionTest exceptionTest = new ExceptionTest();
        try {
            exceptionTest.getException(3);
        } catch (MyException e) {
            System.out.println("异常错误");
        }
    }
}

结果:

       总结一下:异常处理比较合适的方式是使用try...catch...finally...包括整段代码(包括整段代码可能会造成资源上的浪费,但是会有保障性),然后逐级抛出,先抛异常子类,再抛异常父类,最后抛Exception。如果不是最外层调用则catch里不打印堆栈信息,并且throw自定义异常,最外层再对信息进行包装提供给用户,并打印到日志上去。
       
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值