java异常概述

异常关系

这里写图片描述
在Java中提供了一些异常用来描述经常发生的错误,对于这些异常,有的需要程序员进行捕获处理或声明抛出,有的是由Java虚拟机自动进行捕获处理。

Java中常见的异常类:

1. runtimeException子类:

1、 java.lang.ArrayIndexOutOfBoundsException
数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
2、java.lang.ArithmeticException
算术条件异常。譬如:整数除零等。
3、java.lang.NullPointerException
空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等
4、java.lang.ClassNotFoundException
找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
5、java.lang.NegativeArraySizeException 数组长度为负异常
6、java.lang.ArrayStoreException 数组中包含不兼容的值抛出的异常
7、java.lang.SecurityException 安全性异常
8、java.lang.IllegalArgumentException 非法参数异常

2.IOException

IOException:操作输入流和输出流时可能出现的异常。
EOFException 文件已结束异常
FileNotFoundException 文件未找到异常

3. 其他

ClassCastException 类型转换异常类
ArrayStoreException 数组中包含不兼容的值抛出的异常
SQLException 操作数据库异常类
NoSuchFieldException 字段未找到异常
NoSuchMethodException 方法未找到抛出的异常
NumberFormatException 字符串转换为数字抛出的异常
StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常
IllegalAccessException 不允许访问某类异常
InstantiationException 当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常

异常代码执行过程

这里写图片描述

try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
catch块:用于处理try捕获到的异常。
finally块:无论是否捕获或处理异常,finally块里的语句都会被执行。

当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。

在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。

throws和throw

throws:

如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常。
throws语句用在方法定义时声明该方法要抛出的异常类型,如果抛出的是Exception异常类型,则该方法被声明为抛出所有的异常。多个异常可使用逗号分割。

throw

throw总是出现在函数体中,用来抛出一个Throwable类型的异常。程序会在throw语句后立即终止,它后面的语句执行不到,然后在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块。
例如:throw new IOException;


注意:

catch关键字后面括号中的Exception类型的参数e。
Exception就是try代码块传递给catch代码块的变量类型,e就是变量名。
catch代码块中语句”e.getMessage();”用于输出错误性质。 通常异常处理常用3个函数来获取异常的有关信息:

getCause():返回抛出异常的原因。如果 cause 不存在或未知,则返回 null。   getMeage():返回异常的消息信息。  
printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段System.err 的值。    

有时为了简单会忽略掉catch语句后的代码,这样try-catch语句就成了一种摆设,一旦程序在运行过程中出现了异常,就会忽略处理异常,而错误发生的原因很难查找。


自定义异常类:

使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
在程序中使用自定义异常类,大体可分为以下几个步骤。

(1)创建自定义异常类。
(2)在方法中通过throw关键字抛出异常对象。
(3)如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
(4)在出现异常方法的调用者中捕获并处理异常。

http://blog.csdn.net/hguisu/article/details/6155636
http://blog.csdn.net/dr_guo/article/details/50718063

异常链的使用:

正常情况下如果不包装异常,则会默认捕获最近的方法异常,而找不到根本的方法异常

public class LinkedException {
    public static void main(String[] args) {
        try {
            firstMethod();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            System.out.println("*******");
            System.out.println("根本异常位置");
            e.printStackTrace();
            System.out.println("**********");
        }
    }

    private static void firstMethod() throws SQLException{
        try {
            secondMethod();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new SQLException("第二个异常");
        }
    }

    private static void secondMethod() throws IOException{
        try {
            thirdMethod();
        } catch (InputMismatchException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new IOException("第三个异常");
        }   
    }

    private static void thirdMethod() throws InputMismatchException{
        throw new InputMismatchException("根本异常");
    }
}

若main方法调用其他方法,应该要找到下一个异常位置,直到找到根本异常位置为止。
但是catch中的内容输出是这样的:

根本异常位置

    at exception_exrecises.LinkedException.firstMethod(LinkedException.java:27)
    at exception_exrecises.LinkedException.main(LinkedException.java:10)
**********

并没有找到根本异常的位置。这样不利于错误的查找和检查。我们需要封装异常来继续找到根本异常。

public class LinkedException {
    public static void main(String[] args) {
        try {
            firstMethod();
        } catch (SQLException e) {
            // TODO Auto-generated catch block

            System.out.println("*******");
            System.out.println("根本异常位置");
            e.printStackTrace();
            System.out.println("**********");
        }
    }

    private static void firstMethod() throws SQLException{
        try {
            secondMethod();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new SQLException("第二个异常",e);
        }
    }

    private static void secondMethod() throws IOException{
        try {
            thirdMethod();
        } catch (InputMismatchException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new IOException("第三个异常",e);
        }   
    }

    private static void thirdMethod() throws InputMismatchException{
        throw new InputMismatchException("根本异常");
    }
}

方法很简单,在throw异常时,加上现有的异常对象作为封装,继续向上抛出。
这样就输出了根本异常的位置

*******
根本异常位置
java.sql.SQLException: 第二个异常
    at exception_exrecises.LinkedException.firstMethod(LinkedException.java:27)
    at exception_exrecises.LinkedException.main(LinkedException.java:10)
Caused by: java.io.IOException: 第三个异常
    at exception_exrecises.LinkedException.secondMethod(LinkedException.java:37)
    at exception_exrecises.LinkedException.firstMethod(LinkedException.java:23)
    ... 1 more
Caused by: java.util.InputMismatchException: 根本异常
    at exception_exrecises.LinkedException.thirdMethod(LinkedException.java:42)
    at exception_exrecises.LinkedException.secondMethod(LinkedException.java:33)
**********  ... 2 more

它明确指定了异常出现的原因直到根本异常,这才利于我们更好的寻找异常,解决问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值