Java基础知识之异常Exception

1、什么是异常,java提供异常处理机制有什么用?
    以下程序执行过程中发生了不正常的情况,而这种不正常的情况叫做:异常
    java语言是很完善的语言,提供了异常的处理方式,以下程序执行过程中出现了不正常情况,
    java把该异常信息打印输出到控制台,供程序员参考。程序员看到异常信息之后,可以对
    程序进行修改,让程序更加的健壮。

    什么是异常:程序执行过程中的不正常情况。
    异常的作用:增强程序的健壮性。

2、以下程序执行控制台出现了:
    Exception in thread "main" java.lang.ArithmeticException: / by zero
        at com.bjpowernode.javase.exception.ExceptionTest01.main(ExceptionTest01.java:14)
    这个信息被我们称为:异常信息。这个信息是JVM打印的。

3. 异常在java中以类的形式存在,每一个异常类都可以创建异常对象。

4.处理异常的第一种方式:
    在方法声明的位置上使用throws关键字抛出,谁调用我这个方法,我就抛给谁。抛给调用者来处理。
    这种处理异常的态度:上报。

  处理异常的第二种方式:
    使用try..catch语句对异常进行捕捉。
    这个异常不会上报,自己把这个事儿处理了。
    异常抛到此处为止,不再上抛了。

注意:
    只要异常没有捕捉,采用上报的方式,此方法的后续代码不会执行。
    另外需要注意,try语句块中的某一行出现异常,该行后面的代码不会执行。
    try..catch捕捉异常之后,后续代码可以执行。

在以后的开发中,处理编译时异常,应该上报还是捕捉呢,怎么选?
    如果希望调用者来处理,选择throws上报。
    其它情况使用捕捉的方式。

5.深入try..catch
    1、catch后面的小括号中的类型可以是具体的异常类型,也可以是该异常类型的父类型。
    2、catch可以写多个。建议catch的时候,精确的一个一个处理。这样有利于程序的调试。
    3、catch写多个的时候,从上到下,必须遵守从小到大。

6.异常对象的两个方法:
    String msg = e.getMessage();
    e.printStackTrace(); // 一般都是使用这个。

我们以后查看异常的追踪信息,我们应该怎么看,可以快速的调试程序呢?
    异常信息追踪信息,从上往下一行一行看。
    但是需要注意的是:SUN写的代码就不用看了(看包名就知道是自己的还是SUN的。)。
    主要的问题是出现在自己编写的代码上。

例如:

/*
            java.io.FileNotFoundException: C:\jetns-agent.jar (系统找不到指定的文件。)
                at java.base/java.io.FileInputStream.open0(Native Method)
                at java.base/java.io.FileInputStream.open(FileInputStream.java:213)
                at java.base/java.io.FileInputStream.<init>(FileInputStream.java:155)
                at java.base/java.io.FileInputStream.<init>(FileInputStream.java:110)                    //sun的代码
                at com.bjpowernode.javase.exception.ExceptionTest09.m3(ExceptionTest09.java:31)  //自己代码出现的异常
                at com.bjpowernode.javase.exception.ExceptionTest09.m2(ExceptionTest09.java:27)
                at com.bjpowernode.javase.exception.ExceptionTest09.m1(ExceptionTest09.java:23)
                at com.bjpowernode.javase.exception.ExceptionTest09.main(ExceptionTest09.java:14)
                因为31行出问题导致了27行
                27行出问题导致23行
                23行出问题导致14行。
                应该先查看31行的代码。31行是代码错误的根源。

7.关于try..catch中的finally子句:
    1、在finally子句中的代码是最后执行的,并且是一定会执行的,即使try语句块中的代码出现了异常。
        finally子句必须和try一起出现,不能单独编写。

    2、finally语句通常使用在哪些情况下呢?
        通常在finally语句块中完成资源的释放/关闭。
        因为finally中的代码比较有保障。
        即使try语句块中的代码出现异常,finally中代码也会正常执行。

8.finally语句:
    放在finally语句块中的代码是一定会执行的【再次强调!!!】
 */
例一:public class ExceptionTest11 {
    public static void main(String[] args) {
        /*
        try和finally,没有catch可以吗?可以。
            try不能单独使用。
            try finally可以联合使用。
        以下代码的执行顺序:
            先执行try...
            再执行finally...
            最后执行 return (return语句只要执行方法必然结束。)
         */
        try {
            System.out.println("try...");
            return;
        } finally {
            // finally中的语句会执行。能执行到。
            System.out.println("finally...");
        }

        // 这里不能写语句,因为这个代码是无法执行到的。
        //System.out.println("Hello World!");
    }
}
例二:public class ExceptionTest12 {
    public static void main(String[] args) {
        try {
            System.out.println("try...");
            // 退出JVM
            System.exit(0); // 退出JVM之后,finally语句中的代码就不执行了!
        } finally {
            System.out.println("finally...");
        }
    }
}

 

9.反编译.class文件案例    反编译工具DJ  decompile

public class ExceptionTest13 {
    public static void main(String[] args) {
        int result = m();
        System.out.println(result); //100
    }

    /*
    java语法规则(有一些规则是不能破坏的,一旦这么说了,就必须这么做!):
        java中有一条这样的规则:
            方法体中的代码必须遵循自上而下顺序依次逐行执行(亘古不变的语法!)
        java中还有一条语法规则:
            return语句一旦执行,整个方法必须结束(亘古不变的语法!)
     */
    public static int m(){
        int i = 100;
        try {
            // 这行代码出现在int i = 100;的下面,所以最终结果必须是返回100
            // return语句还必须保证是最后执行的。一旦执行,整个方法结束。
            return i;
        } finally {
            i++;
        }
    }
}

/*
反编译之后的效果
public static int m(){
    int i = 100;
    int j = i;
    i++;
    return j;
}
 */

10.final finally finalize有什么区别?
    final 关键字
        final修饰的类无法继承
        final修饰的方法无法覆盖
        final修饰的变量不能重新赋值。

    finally 关键字
        和try一起联合使用。
        finally语句块中的代码是必须执行的。

    finalize 标识符
        是一个Object类中的方法名。
        这个方法是由垃圾回收器GC负责调用的。

11.Java中怎么自定义异常呢?(重要***)
    两步:
        第一步:编写一个类继承Exception或者RuntimeException.
        第二步:提供两个构造方法,一个无参数的,一个带有String参数的。

    死记硬背。
 */
public class MyException extends Exception{ // 编译时异常
    public MyException(){

    }
    public MyException(String s){
        super(s);
    }
}

/*
public class MyException extends RuntimeException{ // 运行时异常

}
 */