java异常

基本概念

        Java中的异常是指程序在运行时发生的不正常情况(开发过程中的语法错误和逻辑错误不是异常)。

异常类型

        执行过程中所发生的异常可以分为两大类:

  Error:

        java虚拟机无法解决的严重问题,会导致程序直接崩溃

  Exception:

        因编程错误或偶然的外在因素导致的一般性问题,可以通过针对性的代码进行处理(如空指针访问,读取不存在的文件等)。同时Exception又可分为两大类:

        [运行时异常]:

        也称非检查型异常(Unchecked Exceptions)。是程序运行时发生的异常,特殊情况可不做处理(即交由系统默认处理方式处理)。例如空指针异常:(NullPointerException)当程序调用某对象并使用,但此时该对象为空时,系统就会抛出该异常:

public class Go {
    public static void main(String[] args) {
        String str1="这是一句话";
        System.out.println(str1.length());
        //正常执行
        String str2=null;
        System.out.println(str2.length());
        //空指针异常
    }
}

        [编译时异常]:

        也称检查型异常(Checked Exceptions)编译器检查出的异常,必须要处理

关系表

Throwable  
    |  
    +-- Error  
    |       |  
    |       +--VirtualMachineError  
    |       |       |  
    |       |       +--OutOfMemoryError  
    |       |       |  
    |       |       +-- ... (其他虚拟机错误)  
    |       |  
    |       +-- ThreadDeath  
    |       |  
    |       +-- ... (其他错误)  
    |  
    +-- Exception  
            |  
            +-- RuntimeException  
            |       |  
            |       +-- ArithmeticException  
            |       |  
            |       +-- NullPointerException  
            |       |  
            |       +-- IndexOutOfBoundsException  
            |       |  
            |       +-- ... (其他运行时异常)  
            |  
            +-- IOException  
            |       |  
            |       +-- FileNotFoundException  
            |       |  
            |       +-- ... (其他I/O异常)  
            |  
            +-- SQLException  
            |       |  
            |       +-- ... (SQL异常)  
            |  
            +-- ... (其他检查型异常)

异常处理

try-catch-finally

        程序在代码中捕获发生的异常,自行处理(选中代码,按ctrl+alt+t快捷键可快速输入)

try {  
    // 尝试执行的代码,可能会抛出异常  
} catch (ExceptionType1 e) {  
    // 当try块中抛出ExceptionType1类型的异常时执行的代码  
    //封装为对象e
} catch (ExceptionType2 e) {  
    // 当try块中抛出ExceptionType2类型的异常时执行的代码  
    // 可以有多个catch块来处理不同类型的异常  
} finally {  
    // 无论是否发生异常都会执行的代码  
    // 通常用于释放资源,如关闭文件、数据库连接等  
}
  • try块:包含可能抛出异常的代码。如果有异常,则执行相对应的catch块。
  • catch块:用于捕获try块中抛出的异常,并将其封装的新对象中。
  • finally块:无论是否发生异常,finally块中的代码都会被执行。

        注意事项

        1、如果try块中有异常发生,就会直接进入catch块,不会再继续向下执行try块中的其他语句;如果没有异常则不执行catch块。

public class Go {
    public static void main(String[] args) {
        String str1="这是句话";
        String str2= null;

        try {//第一个try块
            System.out.println("str1长度:"str1.length());//正确,输出4
            System.out.println("无异常");//继续执行
        } catch (Exception e) {//因无异常,不再执行对应的catch块
            System.out.println("有异常发生");
        }

        try {//第二个try块
            System.out.println("str2长度:"str2.length());//错误,出现异常
            System.out.println("无异常");//不再继续执行
        } catch (Exception e) {//因有异常,直接执行对应的catch块
            System.out.println("有异常发生");
        }
    }
}

执行结果

        字符串str1长度:4
        无异常
        有异常发生 

        2、可以有多个catch块,每个catch块捕获不同类型的异常,要求父类异常在后,子类异常在前。如果发生异常,只会匹配一个catch块。

public class Go {
    public static void main(String[] args) {
        try {
            int num1 = 10;
            int num2 = 0;
            //将0作为除数,会导致算术异常
            System.out.println(num1 / num2);
//下例为空指针异常,在此仅作示例,不执行
//            A a = new A();
//            a = null;
//            System.out.println(a.getClass());
        } catch (NullPointerException e) {//第一个catch块
            System.out.println("空指针异常:" + e.getMessage());
        } catch (ArithmeticException e) {//第二个catch块
            System.out.println("算术异常:" + e.getMessage());
        } catch (Exception e) {//Exceptin为上两例异常的父类,因此放在后面
            System.out.println(e.getMessage());
        }
    }
}

执行结果:

        算术异常:/ by zero

        因为在该例中未发生空指针异常,所以第一个catch块不会被执行 

        3、因为finally块总会被执行的特性,所以其通常用于释放资源,如关闭文件、数据库连接等。也可以仅使用try-finally,这样无论程序是否异常,都会执行finally内的语句,但这种用法相当于未捕获异常,程序有可能崩溃。

throws

        当方法内部使用了可能抛出异常的代码,并且这些方法不想或不能处理这些异常时,它们可以使用 throws 关键字来声明这些异常。这样,调用这个方法的代码就需要负责处理这些异常,或者继续向上层抛出。
        如果该异常一直未被处理,系统就会调用主方法默认的 throws 方法输出异常信息。

声明异常

        在声明方法时使用 throws 关键字,后面跟着一个或多个异常类型(用逗号分隔)。

public void someMethod() throws SomeException, AnotherException {  
    // 方法体  
}

注意事项

        thrwos后面的异常类型可以是方法中产生的异常类型,也可以是它的父类(如NullPointerException可以被替换成其父类Exception)。但注意抛出的异常类型要么和父类一致,要么为父类抛出的异常类型的子类型。

class Father {//父类
    //父类方法抛出的异常类型为RuntimeException
    public void method()throws RuntimeException{}
}
class A extends Father{//子类A
    //正确、子类方法抛出的异常类型为RuntimeException和父类一致
    public void method() throws RuntimeException {
    }
}
class B extends Father{//子类B
    //错误、子类方法抛出的异常类型为RuntimeException的父类
    public void method() throws Exception {
    }
}

自定义异常

        当程序中出现了某种异常,但该异常并未在系统所描述的异常类型中存在,这个时候我们就可以自己设计异常类,用于描述该异常信息。

声明异常

        自定义异常类名继承自Exception或RuntimeException,并添加至少一个无参数的构造函数。如果继承自Exception则属于编译异常,如果继承自RuntimeException则属于运行异常(一般继承RuntimeException)。

public class myE extends Exception {
    public E() {//添加构造函数
    //该异常所需执行的操作  
    }
}

例:判断某一变量的值是否处于1—100之间,如果不是,则抛出异常

public class Go {
    public static void main(String[] args) {
        int num=101;
        if(!(num>=1&&num<=100))//判断该变量是否符合要求
            //抛出自定义异常MYE
            throw  new MYE("变量不在1-100之间");
        System.out.println("变量符合要求");
    }
}
//自定义一个异常
class MYE extends RuntimeException{//继承自RuntimeException,为运行异常
    public MYE(String message) {
        super(message);
    }
}

执行结果:

Exception in thread "main" pack.chn.class1.MYE: 变量不在1-100之间
    at pack.chn.class1.Go.main(Go.java:10)

throw和throws的区别

        不难注意到,上文分别出现了throw和throws,他们之间存在一定区别:

1、意义不同:throws是异常处理的一种方式,throw为自定义异常的关键字
2、位置不同:throws写在声明方法的语句中,throw则在方法体中
2、后续代码不同:throws后写的是异常类型,throw是异常对象

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值