java中的异常

Posted 苦瓜爆炒牛肉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中的异常相关的知识,希望对你有一定的参考价值。

1.什么是异常?

异常就是Java程序在运行过程中出现的错误。

 

2.异常的继承体系

java.lang.Object

    java.lang.Throwable

        java.lang.Error

        java.lang.Exception

            java.lang.RuntimeException

RuntimeException是在Java虚拟机的正常操作期间可以抛出的那些异常的超类。而除了RuntimeException,其他类是编译时异常。

  • 运行时异常与编译时异常有什么区别呢?

所有的RuntimeException类以及其子类的实例被称为运行时异常,其他的异常就是编译时异常

编译时异常:java程序必须显示处理,否则程序就会发生错误,无法通过编译。常见的编译时异常就是打开文件时,必须在编译的时候处理。如果不处理异常,编译通不过。

运行时异常:无需显示处理。运行时异常是代码错误,需要回头更改代码。

 

3.异常的检测、捕获

(1) try ... catch

(2) try ... catch ... finally

(3) try ... finally

try用来检测异常的,catch用来捕获异常的,finally用来释放资源的。

public static void main(String[] args) {
        try{
            int num = 10/0;
        }catch (Exception e){
            System.out.println("除数不能为0");
        }finally {
            System.out.println("我会不会执行?");
        }
    }

// 输出结果:
除数不能为0
我会不会执行?

 

4.打印异常信息

Throwable的几个常见的方法:

(1) getMessage()    获取异常信息,返回字符串

(2) toString()    获取异常类名和异常信息,返回字符串

(3) printStackTrace    获取异常类名和异常信息,以及异常出现在程序中的位置。返回值为void。(jvm默认方式)

public static void main(String[] args) {
        try{
            int num = 10/0;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            System.out.println("我会不会执行?");
        }
    }

// 输出结果:
java.lang.ArithmeticException: / by zero
    at com.pr.Test15.main(Test15.java:6)
我会不会执行?

 

5.主动抛出异常

例如有一个学生类,有两个属性,姓名与年龄。其中年龄需要合法的年龄。这时候可以利用主动抛出异常来避免年龄非法了。

public void setAge(int age) {
        if (this.age > 0 && this.age < 150){
            this.age = age;
        }else {
            throw new RuntimeException("年龄不合法");
        }

抛出RuntimeException,运行时异常。看一下跑出编译时异常的写法:

public void setAge(int age) throws Exception {
        if (this.age > 0 && this.age < 150){
            this.age = age;
        }else {
            throw new Exception("年龄不合法");
        }

可以看到我们需要在方法上面声明,这个方法有异常抛出,你用我的时候,要捕获异常(可以try ... catch 也可以直接 throws)。

总结1:编译时异常的抛出必须对其进行处理

           运行时异常的抛出可以处理也可以不处理

 

总结2:throw与throws的区别

throw:用在方法体内,跟的是异常对象名 。只能抛出一个异常对象名。表示抛出异常,由方法体内的语句处理。

throws:用在方法声明后面,跟的是异常类名。可以跟多个异常类名,用逗号隔开。表示抛出异常,由该方法的调用者来处理。

          

 

6.关于finally

finally里面的代码无论是否发生异常都会执行。关于finally,遇到一道很有意思的题:

public static void main(String[] args) {
        try{
            System.out.println(10/0);
        }catch (Exception e){
            return;
        }finally {
            System.out.println("flag");
        }
    }

catch里面有return,会不会输出flag呢?结果是输出flag。这样是不是意味者先执行System.out.println("flag"),然后再执行return呢?

再看一道题:

 

public class Test16 {
    public static void main(String[] args) {
        System.out.println(Demo.test());
    }
}

class Demo{
    public static int test(){
        int i = 10;
        try{
            i = 20;
            System.out.println(10/0);
            return i;
        }catch (Exception e){
            i = 30;
            return i ;
        }finally {
            i = 40;
        }
    }
}

 

按照上面的逻辑,输出结果应该是40。但是真实的运行结果是30。为什么呢?

其实在运行到catch的时候,i 赋值为30,然后return i 给 i 建立了返回的通道,然后再执行finally语句,最后 return 。

 

 

7.自定义异常

class AgeOutOfRangeException extends Exception{
    public AgeOutOfRangeException() {
    }

    public AgeOutOfRangeException(String message) {
        super(message);
    }
}

 

8.异常注意事项

(1)子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。

(2)如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常

(3)如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

以上是关于java中的异常的主要内容,如果未能解决你的问题,请参考以下文章

java.lang.NullPointerException: Attempt to invoke virtual method ‘int android.database.sqlite异常(代码片段

片段中的Android致命异常

异常和TCP通讯

片段中的getView()导致抛出异常,不确定原因

java 反射代码片段

片段中的空指针异常