关于java:万字长文总结深度剖析那些Java开发中碰到的异常一次性全帮你处理掉

异样是什么

在现实状态下,用户输出的数据的格局永远都是正确的,抉择关上的文件也肯定存在,并且永远不会呈现Bug。——《Java核心技术》

为了防止用户在程序运行的过程中呈现谬误等,Java应用了一种称为异样解决机制的谬误捕捉机制来进行解决异样的状况。

以下均为针对异样解决机制进行的形容与补充。

概述

Java中异样的层次结构(次要)如下图。

由上图可知,Throwable 是Java语言中所有谬误和异样的类。只有作为此类(或其一个子类)的实例的对象由Java虚拟机抛出,或者能够由Java throw语句抛出。 相似地,只有这个类或其子类能够是catch子句中的参数类型。

补充:
unchecked:未查看异样。
checked:已查看异样。

什么时候会抛出异样?

如果遇到了无奈解决的状况,那么java的办法能够抛出一个异样。那么什么状况下可能抛出异样呢?

1、用户输出谬误
2、设施谬误
3、物理限度
4、程序呈现谬误。 —– 例如,a[-1]=0会抛出ArrayIndexOutOfBoundsException的uncheck异样。
5、调用一个抛出已查看的办法。—– 例如,。public FileInputStream(String name) throws FileNotFoundException
6、程序运行中发现的谬误
7、Java虚拟机和运行时库呈现的外部谬误

抛出&捕捉异样?

此章节次要是关键字throws、throw、和try-catch(finally)的作用及区别。

【补充】JVM对异样的解决办法 :打印异样的跟踪栈信息,并终止程序运行。

抛出异样

(1)throws通常在办法首部的申明后抛出异样。

class MyAnimation{  
    public Image loadImage(String s) throws IOException{
        ...
    }
}
  • throws抛出的是可能产生的异样。(并不一定会产生这些异样)
  • 当该办法被调用的时候必须捕捉,或者也能够再次抛出异样,最终由Java虚拟机解决。
  • 用来申明一个办法可能产生的所有异样(用,分隔), 不做任何解决而是将异样往上传,谁调用我我就抛给谁。

    throw关键字通常用在办法体中,并且抛出一个异样对象。

    String readData(Scanner in)throws EOFException{  
        while(...){    
            if(!in.hasNext())//遇到EOFException异样    
            if(n<len){      
                throw new EOFException();    
            }...  
        }
    }
*  throw则是抛出了异样,执行throw则肯定抛出了某种异样。
* throw语句由办法体内的语句解决。
* 只能抛出一个异样对象。
* 有两种形式捕捉。要么本人捕捉异样 try-catch 代码块,要么是抛出一个异样(throws 异样)。
## 小总结
------由上述throws、throw比拟可知。
(1)throw抛出一个异样对象时须要由函数的下层调用解决这个异样,此时,能够通过try-catch(finally)代码块,也能够通过throws进行抛出。(肯定要解决)
(2)throws抛出一个可能的异样时能够不对此异样进行解决。

编译时异样须要手动进行解决;而运行时异样jvm会打印异样的跟踪栈信息,并终止程序运行。
所以个别运行时异样不须要手动捕捉,但编译时异样须要手动解决。

# 捕捉异样(try-catch-finally)
* 编写代码须要用到异样捕捉的时候。
* java中即便不会产生异样的代码也是能够用try-catch进行捕捉。
【注】在定义一个办法的时候,能够应用throws关键字申明,应用throws申明的办法示意此办法不解决异样,而是交给办法的调用处进行解决。
【注】应用了throw,抛出了异样,必然要进行捕捉和解决,就是说,必须要进行try-catch解决或者throws抛出。

应用1:

try
{
//须要被检测的异样代码
}catch(Exception e){

//异样解决,即解决异样的代码(打印异样信息并解决)

}finally{
  //肯定会被执行的代码(通常能够进行资源的革除工作)
}

应用2:

try
{
//须要被检测的异样代码
}catch(Exception e){

//异样解决,即解决异样的代码(打印异样信息并解决)

}

应用3:

try
{
//须要被检测的异样代码
}finally{
  //肯定会被执行的代码(通常能够进行资源的革除工作)
}

try
{
//须要被检测的异样代码
}catch(Exception e1){

//异样解决,即解决异样的代码(打印异样信息并解决)

}catch(IOException e2){

//异样解决,即解决异样的代码(打印异样信息并解决)

}//能够通过catch解决多个异样。

---------举个栗子-------

public class TestException {

//测试0
boolean testEx() throws Exception{
    boolean res = true;
    try{
        res = testEx1();//执行
    }catch (Exception e){
        System.out.println("测试0,捕捉异样");
        res = false;
        throw e;
    }finally{
        System.out.println("测试0, finally 最终返回的值 =" + res);
        return res;
    }
}
//测试1
boolean testEx1() throws Exception{
    boolean res= true;
    try{
        res = testEx2();
        if (!res){
            return false;
        }
        return res;
    }catch (Exception e){
        System.out.println("测试1, catch捕捉");
        res = false;
        throw e;
    }finally{
        System.out.println("测试1, finally最终返回值 =" + res);
        return res;
    }
}
//测试2
boolean testEx2() throws Exception{
    boolean res = true;
    try{
        int b = 2;
        int c;
        for (int i = 2; i >= 0; i--){
            c = b / i;
            System.out.println("c="+c+"\ti=" + i);
        }
        return true;
    }catch (Exception e){
        System.out.println("测试2, catch捕捉");
        res = false;
        throw e;
    }finally{
        System.out.println("测试2, finally最终值 =" + res);
        return res;
    }
}

}//借鉴Angel_Kitty的例子

上述后果
![](https://upload-images.jianshu.io/upload_images/23140115-bac5d8684ba514e0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



# 如何抛出异样?(举个栗子叭)
此节次要形容对抛出异样以及捕捉异样的整个过程的实例。包含自定义异样类等。

## 自定义接口抛出异样

public interface ComparePerson {

//    比拟两个Person,是否相等
void compareInfo(Person person1,Person person2) throws MyException;

}

## 自定义异样类

//自定义的异样类(须要继承Exception才是异样类)
class MyException extends Exception{

public MyException(String s){//输入异样信息
    System.out.println(s);
}

}

#3 定义一个类去实现此接口

public class Person implements ComparePerson {

//    姓名
private String name;
//    年龄
private int age;

public Person(String name, int age) {
    this.name = name;
    this.age = age;
}

// 两个Person不相等,则抛出自定义异样,打印2集体的信息,以及不相等的信息

@Override
public void compareInfo(Person person1, Person person2) {
    try{
        System.out.println(person1.compare(person2));
    }catch (MyException e){

// e.printStackTrace();

    }
}

// 比拟两个对象是否雷同,不雷同时抛出异样并输入异样信息

public String compare(Object obj) throws MyException {//compareInfo办法在接口中抛出了异样,此时调用了compare办法也须要抛出想应的异样。

// 判断2个对象的地址是否雷同

    if (this == obj) {
        return "2集体属性完全相同";
    }

// 判断obj对象是否是Person的派生类(子类)

    if (obj instanceof Person) {
        System.out.println("********");
        Person obj1 = (Person) obj;//强制转换肯定胜利
        if (obj1.getName().equals(this.name) && obj1.getAge() == this.age) {
            throw new MyException("2集体属性雷同!");//须要调用此办法的下层调用者throws 此异样或者应用try-catch语句捕捉异样。
        } else if (obj1.getAge() == this.age) {
        //打印对象的详细信息
            System.out.println(this.toString());
            System.out.println(obj1.toString());
            throw new MyException("2集体姓名不同~");
        } else if (obj1.getName().equals(this.name)) {
        //打印对象的详细信息
            System.out.println(this.toString());
            System.out.println(obj1.toString());
            throw new MyException("2集体年龄不同~");
        }
    }
    return "2集体不同a";

}

//打印各参数
public String toString() {
    return "name is:" + this.name + "\tage is:" + this.age;
}
//set get办法
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

}

## 测试主类加载测试

class TestMain {

public static void main(String[] args) throws MyException {

// 2个Person对象

    Person person1 = new Person("掰掰", 18);
    Person person2 = new Person("憨憨", 18);
    person1.compareInfo(person1, person2);

}

}

上述后果
![](https://upload-images.jianshu.io/upload_images/23140115-60d492d03de05419.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

class TestMain {

public static void main(String[] args) throws MyException {

// 2个Person对象

    Person person1 = new Person("掰掰", 18);
    Person person2 = new Person("掰掰", 18);
    person1.compareInfo(person1, person2);

}

}


![](https://upload-images.jianshu.io/upload_images/23140115-a7cc76ccaf6af416.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

class TestMain {

public static void main(String[] args) throws MyException {

// 2个Person对象

    Person person1 = new Person("掰掰", 18);
    Person person2 = new Person("掰掰", 20);
    person1.compareInfo(person1, person2);
}

}

![](https://upload-images.jianshu.io/upload_images/23140115-cfb95fa64748a4e3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


【注】上述Person类中,正文了 e.printStackTrace()办法,如果勾销正文,会打印相应抛出的异样信息。如下图:
![](https://upload-images.jianshu.io/upload_images/23140115-838a5f5d2e8ad65f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


上述抛出的异样就是自定义的异样信息。

能够拿着上述例子间接运行一下哦,还能够再此例子进行更深入的学习!
# 最初
在文章的最初作者为大家整顿了很多材料!包含java外围知识点+全套架构师学习材料和视频+一线大厂面试宝典+面试简历模板+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书等等!

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理