Java异常类关系图

所有类 都以Throwable为顶层父类

分为2大类

——错误:Error类以及他的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理,Error很少出现。

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

 

进一步将异常分为2大类:非检查异常  检查异常  (根据是否需要javac编译器检查来区分

 

——非检查异常  Error 和 RuntimeException 以及他们的子类。

javac在编译时,不会发现这样的异常,不强制要求程序处理这些异常。但可以编写代码处理(使用try…catch…finally)这样的异常,也可以不处理。对于这些异常,我们应该修正代码,而不是去通过异常处理器处理 。非检查异常发生的原因多半是代码编写逻辑问题。

——如除0错误ArithmeticException

——错误的强制类型转换错误ClassCastException

——数组索引越界ArrayIndexOutOfBoundsException

——使用了空对象NullPointerException等等

 

——检查异常 除了Error 和 RuntimeException的其它异常。

javac强制要求程序员可能发生的这样的异常做预备处理工作(使用try…catch…finally或者throws)。在方法中要么用try-catch语句捕获它并处理,要么用throws子句声明抛出它,否则编译不会通过。这样的异常一般是由程序的运行环境导致的。因为程序可能被运行在各种未知的环境下,而程序员无法干预用户如何使用他编写的程序,于是程序员就应该为这样的异常时刻准备着。

——数据库读写出错 SQLException 

——输入输出异常IOException

——类加载出错 ClassNotFoundException 等

 

try   catch  finally 块是一个典型的异常处理块

try中执行过程可能抛出异常

catch捕获异常 并处理

finally中语句总是会执行

 

throws关键字

——经典写法  void fun() throws IOException,SQLException{}

 

——当子类重写父类的带有 throws声明的函数时,其throws声明的异常必须在父类异常的可控范围内——用于处理父类的throws方法的异常处理器,必须也适用于子类的这个带throws方法 。这是为了支持多态。

例如,父类方法throws 的是2个异常,子类就不能throws 3个及以上的异常。父类throws IOException,子类就必须throws IOException或者IOException的子类。

 

public class Exception_Test {

	public static void main(String[] args)
    {
        Father[] objs = new Father[2];
        objs[0] = new Father();
        objs[1] = new Son();
 
        for(Father obj:objs)
        {
        //因为Son类抛出的实质是SQLException,而IOException无法处理它。
        //那么这里的try。。catch就不能处理Son中的异常。
        //多态就不能实现了。
            try 
            {
                 obj.start();
            }catch(IOException)
            {
                 //处理IOException
            }
         }
   }

}
class Father
{
    public void start() throws IOException
    {
        throw new IOException();
    }
}
 
class Son extends Father
{
    public void start() throws Exception
    {
        throw new SQLException();
    }
}

 

 

finally块和return

try块中即便有return,break,continue等改变执行流的语句,finally也会执行。

 

try…catch…finally中的return 只要能执行,就都执行了,

他们共同向同一个内存地址(假设地址是0×80)写入返回值,

后执行的将覆盖先执行的数据,而真正被调用者取的返回值就是最后一次写入的。

finally中的return 会覆盖 try 或者catch中的返回值。

 

案例演示:

public static void main(String[] args)
    {
        int result;
 
        result  =  foo();
        System.out.println(result);     /2
 
        result = bar();
        System.out.println(result);    /2
    }
 
   
    public static int foo()
    {
        try{
            int a = 5 / 0;
        } catch (Exception e){
            return 1;
        } finally{
            return 2;
        }
 
    }
 
   
    public static int bar()
    {
        try {
            return 1;
        }finally {
            return 2;
        }
    }

 

最终的返回值是Finally中的return  

java 异常的父子类谁先被捕获 java中所有异常的父类是_java 异常的父子类谁先被捕获