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

3次阅读

共计 5806 个字符,预计需要花费 15 分钟才能阅读完成。

异样是什么

在现实状态下,用户输出的数据的格局永远都是正确的,抉择关上的文件也肯定存在,并且永远不会呈现 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 架构实战电子书等等!
正文完
 0