Java基础系列四、异常处理

1、异常顶层父类~Throwable类

  Throwable类是Java异常类型的顶层父类,Throwable又派生出Error类和Exception类。

  错误:Error类   以及他的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理,Error很少出现。因此,程序员应该关注Exception为父类的分支下的各种异常类。

  异常:Exception类   以及他的子类,代表程序运行时发送的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。

2、运行时异常、非运行时异常

  根据Javac对异常的处理要求,将异常类分为2类。

    非检查异常(unckecked exception)也叫运行时异常:即编译时不会产生异常,运行产生异常。Error 和 RuntimeException 以及他们的子类。。这样的异常发生的原因多半是代码写的有问题。如除0错误ArithmeticException,

  错误的强制类型转换ClassCastException,数组索引越界ArrayIndexOutOfBoundsException,使用了空对象NullPointerException等等。

    检查异常(checked exception)也叫非运行时异常:即不管你代码写的正确与否,你都要进行处理,因为JVM认为你这段代码产生的异常的概率大。本质:是因为你调用的那些方法在底层实现时就抛出了异常。。除了Error 和 RuntimeException的其它异常。javac强制要求程序员为这样的异常做预备处理工作(使用try…catch…finally或者throws)。

如SQLException , IOException,ClassNotFoundException 等。

3、异常处理语法

  1.、对于检查异常,有2种不同的处理方式:使用try…catch…finally语句块处理它。或者,在函数签名中使用throws 声明交给函数调用者caller去解决。

  2、注意点:

    1、try块中的局部变量和catch块中的局部变量(包括异常变量),以及finally中的局部变量,他们之间不可共享使用。

    2、 try块中存放放可能产生异常对象的代码,如果检测 try块中代码不产生异常,就不会执行catch块代码。否则,当try代码块产生异常对象时,会自动执行catch代码块,并且将异常对象传递给参数 e.

    3、try{}代码块产生的异常一定要是catch中参数的 真正异常的类型 或者是其 子类

    4、 每一个catch块用于处理一个异常。异常匹配是按照catch块的顺序从上往下寻找的,如果同一个try块下的多个catch异常类型有父子关系,异常子类 要放在 异常父类 的前面.

     如果所有的catch都抓不住,可能就相当于我们没有处理到,又可能由JVM处理

    5、finally块不管异常是否发生,只要对应的try执行了,则它一定也执行。只有一种方法让finally块不执行:System.exit()。

     因此finally块通常用来做资源释放操作:关闭文件,关闭数据库连接等等。良好的编程习惯是:在try块中打开资源,在finally块中清理释放这些资源。

    6、 try{}catch{}   ,  try{} finally{}  ,  try{}catch{}finally{} 这三种写法是正确的。

4、获取异常信息的方法

     Throwable父类中  常用的三个方法 用来获得对象中的异常描述信息

      try{
            System.out.println(10/0);
        }catch (ArithmeticException e) {
            //  e.printStackTrace();             //打印异常对象  堆栈详细信息 ,
            System.out.println(e.getMessage()); //获取错误信息
            System.out.println(e.toString());  //返回此 throwable 的简短描述 
        }

/ by zero
java.lang.ArithmeticException: / by zero

5、常见的异常类

public static void main(String[] args) {
        //多重异常捕获(多重catch块):对产生的异常对象逐个去进行匹配,直到匹配成功为止
        //注意  异常子类  要放在  异常父类  的前面
        try {
            Integer a = new Integer("aa你好");
        }
        catch (NullPointerException e) {
            System.out.println("空指针异常");
        } 
        catch (ArithmeticException e) {
            System.out.println("算术异常");
        } 
        catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组索引越界异常");
        } 
        catch (ClassCastException e) {
            System.out.println("类型转换异常");
        }
        catch(NumberFormatException e){
            System.out.println("数字格式异常");
        }
        catch (Exception e) {
            System.out.println("你是个异常,我就能治好你");
        }
     finally{
      System.out.println("只要执行了try块,我总会执行");
     }
        System.out.println("end");
    }
结果:   
数字格式异常
只要执行了try块,我总会执行
end

  

6、自定义异常   

 如果要自定义异常类,则扩展Exception类即可,因此这样的自定义异常都属于检查异常(checked exception)。如果要自定义非检查异常,则扩展自RuntimeException。

throw、throws的区别 

  throw  用来创建异常对象,在方法里面, 后面只能够跟一个具体的异常对象

  throws  用来申明我这个方法中的某段代码有异常。 在方法签名后面,即在() {}之间,    后面跟多个异常类型

package cm.异常处理;
/*  自定义异常的流程  :下面是第一步:
 * ① 自定义一个类
 * ② 继承 Exception 或者 RuntimeException
 * ③ 提供一个公共无参数的构造方法和一个String参数的构造方法
 */
public class MuException extends Exception {
    private static final long serialVersionUID = 1L;
    
    public MuException() {
        super();
    }
    public MuException(String message) {
        super(message);
    }
}
package cm.异常处理;
/*
 * 第二步: 设计一个注册Register的方法,根据条件判断在适当的时候抛出(产生)一个上面1的异常对象,抛出去。
 */
public class Register {
    private static String[] users = { "小王", "小李", "小明" };// 写一个数组,模拟已经注册的用户
    //注册用户名的方法
    public static void register(String userName) throws MuException{
        for(int i=0;i<users.length;i++){
            // 条件判断,如果用户名不为空,且已经存在,则抛出一个MultipleException异常
            if(userName!="" && userName.equals(users[i])){
                // throw:在方法里向调用者抛出异常
                throw new MuException("亲,用户名:" + userName + "已经注册,请重新输入!");
            }
        }
        //没有重复,则注册成功
        System.out.println("恭喜你,注册成功!玩的开心!!");
    }
}
package cm.异常处理;

public class TestRegister {

    public static void main(String[] args) {
        try{
            Register.register("哈哈");
        }catch(MuException e){
            e.printStackTrace();
        }
        
        try{
            Register.register("小王");
        }catch(MuException e){
            e.printStackTrace();
        }
    }

}

结果;
恭喜你,注册成功!玩的开心!!
cm.异常处理.MuException: 亲,用户名:小王已经注册,请重新输入!
at cm.异常处理.Register.register(Register.java:13)
at cm.异常处理.TestRegister.main(TestRegister.java:14)

  

原文地址:https://www.cnblogs.com/gshao/p/10073325.html