java中异常的使用及注意事项

异常:在运行时发生的不正常情况

public class ExceptionDemo{
    public static void main(String[]args){
        int []arr = new int[3];
        System.out.println(arr[3]);
    }
}

异常处理办法:

早期时:以前正常流程代码和问题处理代码相结合, 劣势:问题处理代码和正常流程代码结合一起,阅读性差

 现在将正常流程代码和问题处理代码分离。        
if(time<0){
            new FuTime();//代表着时间为负的情况,这个对象中会包含着问题的名称,信息,位置等信息。
        }

java对异常的处理方法。

在java中用类的形式,对不正常情况进行了描述和封装对象。

1.其实异常就是java通过面向对象 的思想将问题封装成了对象。用异常类进行描述。

2.不同的问题用不同的类进行具体的描述,例:数组角标越界,角标为空。所以问题有多少,异常类有多少,将其共性向上抽取,形成了异常体系。
3.异常体系

该体系特点:子类的后缀名都是用其父类名作为后缀,可读性高

最终错误分为了两大类:

Throwable:异常类的共同父类,具有可抛性,无论是error还是异常,都是问题,
问题发生就应该可以跑出,让调用者知道并处理,该体系的特点就在于Throwable 及其所有的子类都具有可抛性
1.一般不可处理的(用error类来表示) 特点:是由jvm抛出的严重性的问题,这种问题发生一般不针对性处理,直接修改程序。
2.可以处理的(用exception类来表示)

可抛性:

能够被throw,throws这两个关键字所操作的类和对象都具备可抛性。

虚拟机在发生异常的位置新建对象,记录发生错误的位置,错误类型,名称。然后将该对象封装后抛出,给调用者(最终抛给虚拟机)。

当代码执行到发生异常的位置时,会终端代码的执行,抛出异常,异常代码后的代码不执行。

抛出异常时的提醒信息可以自定义:

//可以自行更改条件尝试不同输出
class Demo{
    public int method(int[]arr,int index){

        if(arr==null){
            throw new NullPointerException("数组的引用不能为空");
        }
        if(index>=arr.length){
            throw new ArrayIndexOutOfBoundsException("数组的角标越界了,你是不是疯了,哥们儿:"+index);
        }
        if(index<0){
            throw new ArrayIndexOutOfBoundsException("数组的角标为负整数了,哥们,你是真疯了:"+index);
        }
        return arr[index];
    }
}

class ExceptionDemo2{
    public static void main(String[]args){
        int []arr = new int [3];
        Demo d = new Demo();
        int num = d.method(arr,-30);
        System.out.println("num="+num);
        System.out.println("over");
    }
}

自定义异常:

对于角标是整数不存在,可以用角标越界来表示。 对于负数为角标的情况,准备用负数角标异常来表示。
负数角标异常这种异常在java中并没有定义过。 那就按照java异常的创建思想,面向对象,将负数角标进行自定义描述,并将其封装成对象。
这种自定义的问题描述,称为自定义异常。
//如果让一个类成为异常类,必须要继承异常体系,因为只有成为异常体系的子类才具有可抛性,才能被throw,throws所操作。
//如果一个方法内部可能出现异常,要在方法上先进行异常声明,不然会出现未报告的异常错误。

//主类
class ExceptionDemo3{

public static void main(String[]args) throws FuShuIndexException{
    int []arr = new int [3];
        Demo d = new Demo();
        int num = d.method(arr,-30);
        System.out.println("num="+num);
        System.out.println("over");
}
}
//自定义异常类
class FuShuIndexException extends Exception{
    void FuShuIndexException(){

    }
    FuShuIndexException(String msg){
        super(msg);//调用父类方法
    }

}
//Demo类
class Demo{
    public int method(int[]arr,int index) throws FuShuIndexException{
        if(index<0){
            throw new FuShuIndexException("角标变成负数了");
        }
        return arr[index];
    }
}

throw与throws的区别:

throw 修饰对象
throws修饰类

异常的分类:

1.编译时被检测异常:只要是Exception和其子类都是,除了特殊子类RuntimeException体系和其子类。 这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式。 这样的问题都可以针对性处理。
2.编译时不检测异常(运行时异常):就是Exception中的Runtime体系和其子类 这种问题的发生,无法让功能继续,运算无法进行,更多是因为调用者原因导致的,或者引发了内部状态的改变导致的。
那么这种问题一般不处理,直接编译通过,在运行时让调用时的程序强制停止,让调用者对代码进行更正

对异常的处理方法:

当知道调用的方法可能会有的异常能处理的时候,就捕获(try ,catch) 如果对此异常处理不了,就直接抛出

使用try,catch捕获异常,问题解决后会继续运行下面的代码。

class ExceptionDemo3{

public static void main(String[]args){
    int []arr = new int [3];
        Demo d = new Demo();
        try{
            int num = d.method(arr,-30);
            System.out.println("num="+num);
        }catch(FuShuIndexException e){
            System.out.println("message:"+e.getMessage());
            System.out.println(e);//输出语句中,会自动调用对象的toString方法,而且任何类都有toString方法。
            e.printStackTrace();//jvm默认的异常处理机制
            System.out.println("负数角标异常");
        }

        System.out.println("over");
}
}

class FuShuIndexException extends Exception{
    void FuShuIndexException(){

    }
    FuShuIndexException(String msg){
        super(msg);
    }

}
class Demo{
    public int method(int[]arr,int index) throws FuShuIndexException{
            if(index<0){
            throw new FuShuIndexException("角标变成负数了");
            }
        return arr[index];
    }
}

当一个try会出现多个异常的时候,写多个catch即可
如果在多个catch中存在Exception类时,这个catch要写在最后一个,否则编译失败。

class ExceptionDemo3{

public static void main(String[]args){
    int []arr = new int [3];
        Demo d = new Demo();
        try{
            int num = d.method(null,30);
            System.out.println("num="+num);
        }catch(FuShuIndexException e){
            e.printStackTrace();//jvm默认的异常处理机制
        }catch(NullPointerException e){
            e.printStackTrace();
        }

        System.out.println("over");
}
}

class FuShuIndexException extends Exception{
    void FuShuIndexException(){

    }
    FuShuIndexException(String msg){
        super(msg);
    }

}
class Demo{
    public int method(int[]arr,int index) throws NullPointerException,FuShuIndexException{
            if(arr==null){
                throw new NullPointerException("没有任何数组实体");
            }
            if(index<0){
            throw new FuShuIndexException("角标变成负数了");
            }
        return arr[index];
    }
}

异常的处理原则:

1。方法内部如果抛出需要检测的异常,那么方法上必须要声明。或者在方法内用try,catch捕捉,否则编译失败。
2。如果调用到了声明异常的方法,要么try,要么throws,否则编译失败。
3。见到异常就要做处理,能够处理的进行try,不能处理的直接抛出。
4。一个功能如果抛出了多个异常,那么调用时,必须有多个对应的catch进行针对性处理。内部几个异常,就需要几个catch

finally:其中的代码一应会执行,除非是虚拟机结束了(System.exit(0))
通常用于释放资源。

try catch finally组合特点:

1.try catch finally
2.try catch(多个) 没有必要资源需要释放时,可以不用定义finally.
3.try finally ,异常可以抛出,但是自己打开的资源必须关掉,否则会浪费资源 void show() throws Exception{ try{
//开启资源
throw new Exception; } finally{
//关闭资源 } }

异常的注意事项:

1.子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的子类
2.如果父类抛出多个异常,那么子类只能抛出父类异常的子集。
3.如果父类的方法没有抛出异常,那么子类覆盖时绝对不能抛出异常。

猜你喜欢

转载自blog.csdn.net/ILYPTING/article/details/71298939