异常处理

在异常处理中即使没有main函数 仍然可以正确执行

Exception

1.非检查异常:空指针异常,数组下标越界异常,类型转换异常,算术异常

2.检查异常:文件异常,SQL异常

 

1.try...catch...finnally简单例子

package pro;

import java.util.InputMismatchException;
import java.util.Scanner;

public class TryCatchTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        //divider除数,result结果
        TryCatchTest it = new TryCatchTest();
        int result1 = it.test();
        System.out.println("程序结束了"+result1);
        int result2 = it.test2();
        System.out.println("执行了finally的异常处理"+result2);
        
        

    }
    public int test()
    {
        int divider = 10;
        int result = 100;
        try
        {
            while(divider>-1)
            {
                divider--;
                result = result + 100/divider;
            }
            return result;    
        }catch(Exception e)
        {
            e.printStackTrace();
            System.out.println("程序抛出异常了");
            return -1;
            
        }
        
    
        
    }
    public int test2()
    {
        int divider = 10;
        int result = 100;
        try
        {
            while(divider>-1)
            {
                divider--;
                result = result + 100/divider;
            }
            return result;    
        }catch(Exception e)
        {
            e.printStackTrace();
            System.out.println("程序抛出异常了");
            return result =999;
            
        }
        finally
        {
            System.out.println("这是我的finally。");
            System.out.println("这是result的值"+result);
        }
    
    }

}

注:finally是一定执行的。打印输出异常信息是 (Exception )e.printStackTrace();

2.向上级抛出异常 throw

 

3.用户自定义的异常 class 自定义异常类 extends 异常类型{}   (注:所有自定义的异常都是继承或者间接继承Exception)

异常链:

package pro;

public class ChainTest {

    /**
     * test1:抛出喝大了异常
     * test2:调用test1,捕获喝大了异常,并且包装成运行时异常,继续抛出
     * mian方法中,调用test2,尝试捕获test2捕获的异常
     */
    
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        ChainTest ct = new ChainTest();
        try
        {
            ct.test2();
        }catch(Exception e)
        {
            e.printStackTrace();
        }
        

    }
    public void test1 () throws DrunkException
    {
        throw new DrunkException("开车别喝酒");
    }
    public void test2()
    {
        try {
            test1();
        } catch (DrunkException e) {
            // TODO 自动生成的 catch 块
            RuntimeException runExc = new RuntimeException("司机一滴酒,亲人两行泪");
            runExc.initCause(e);
            throw runExc;
        }
    }

}

新定义的异常中包括产生原始异常的原因.

   initCase():这个方法就是对异常来进行包装的,目的就是为了出了问题的时候能够追根究底。因为一个项目,越往底层,可能抛出的异常类型会用很多,如果你在上层想要处理这些异常,你就需要挨个的写很多catch语句块来捕捉异常,这样是很麻烦的。如果我们对底层抛出的异常捕获后,抛出一个新的统一的异常,会避免这个问题。但是直接抛出一个新的异常,会让最原始的异常信息丢失,这样不利于排查问题。举个例子,在底层会出现一个A异常,然后在中间代码层捕获A异常,对上层抛出一个B异常。如果在中间代码层不对A进行包装,在上层代码捕捉到B异常后就不知道为什么会导致B异常的发生,但是包装以后我们就可以用getCause()方法获得原始的A异常。这对追查BUG是很有利的。

简化代码

 实际应用中的经验与总结:

1.在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常

2. 尽量去处理异常,切忌只是简单的调用printStcackTrace()去打印输出

3.尽量添加finally语句块去释放占用的资源

posted @ 2018-01-31 21:04  helloWorldhelloWorld  阅读(118)  评论(0)    收藏  举报