java之异常
Java之异常
1、概述
在java编程过程中,程序可能会出现了问题,但是出现了问题,如何能快速定位到问题出现在哪里?
所以如果在编程过程中出现了异常,那么我们应该立刻定位到对应的位置,并对产生异常的程序来进行解决。
对于可能出现异常的代码,我们要来做怎样的处理?需要我们自己在编写代码的过程中自己处理掉还是由调用方处理掉,这是个问题。
所以围绕着这两个面来介绍java中的异常。这个也是编程中最最最常用的地方之一。
2、体系介绍
在java的体系结构中提供了Throwable类和两个常用的子类Error (java.lang)、Exception (java.lang)
Error:我们开发人员无法去对其进行避免,只能说提前预防。
Exception:由于开发人员使用不当,可能会出现的一些问题。这个通过正确操作,是可以来进行避免的。java提供了这个类来解决问题。在java中,异常是一个类,产生了异常的本质原因就是创建了一个异常对象,对象中记录了可能出现问题的原因、类型和地方。出现了异常,如果没有进行处理,将会导致当前线程发生终止,从而会中断当前线程下程序的运行。
3、Throwable有用的方法
在Throwable父类中提供了两个可用的方法来帮助我们来快速定位到发生异常的方法,因为子类继承了Throwable之后,可以访问父类中的方法,所以子类中可以来进行调用
包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace
public void printStackTrace():打印异常的详细信息。
public String getMessage():获取发生异常的原因,也就是说是什么原因导致出现了问题的。
用例子来说明异常:
public class ExceptionOne {
public static void main(String[] args) {
int[] arr = {1,2,3};
// 输出第四个元素
System.out.println(arr[4]);
}
}
控制台输出:这里是JVM自己来给我们报出来的异常
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4 // 异常的类型,异常出现的原因
at com.guang.exceptiondemo.ExceptionOne.main(ExceptionOne.java:7) // 异常出现的位置
Process finished with exit code 1 // 中断了程序运行
4、开发人员关注的点
异常分类:编译期异常和运行期异常
在编译期就开始检查错误,如果没有处理,编译都不会通过;
运行期异常,如果运行期间出现了异常,编译期间通过,但是运行会报错。这里是要我们避免的!
我们更加关注的是对异常的处理,java提供了五个关键字来帮助我们解决对异常的处理方式。try、catch、finally、throw、throws
5、对于已知异常的处理
搭配方式:
第一种:最常用的
try{
// 可能会异常的地方
}catch(异常声明){
// 处理方式
}
第二种:
try{
// 可能会异常的地方
}catch(异常声明){
// 处理方式
}finally{
// 不管上面的执行还是不执行,这里都将会执行。只要上面发生的异常中没有发生终止线程运行的。
}
第三种:
try{
// 可能会异常的地方
}finally{
// 不管上面的执行还是不执行,这里都将会执行。只要上面发生的异常中没有发生终止线程运行的。
}
如果try中出现了异常,将会先执行finally中的逻辑,然后try中的异常再进行抛出。
底层源码中会遇到。
6、对于未知异常的处理
对throw和throws的使用
上面的表示的是知道了如何对程序进行处理,这种情况是不知道如何对程序来进行处理的,这里抛出异常,让异常交给谁调用了可能存在异常的方法的所在的方法来进行处理。
使用模板:
方法修饰符 返回值类型 方法名称A() throws 异常类型1,异常烈性2...{
xxxxxxxx;
throw new 异常类型(异常的提示);
}
那么上面的方法肯定是让对象来进行调用的,调用之后如何来进行处理:
try{
对象.方法名称A;
}catch(异常类型1){
}catch(异常类型2){
}
需要注意的是上面的catch代码中,异常之间不能随便乱放。这里进行多个异常处理针对的是方法名称A中的声明的异常的细粒度处理。
通常我们可以采用粗粒度的处理,直接使用他们的父类Exception来进行处理。
对于这块的处理,也有很多问题需要注意,但是我在这里就不再进行过细的总结。
7、自定义异常类
大多数使用的异常类都在java中定义好了,但是我们有时候希望针对自己的业务中存在的异常做一些针对性的处理。比如说我们在给用户设置年龄的时候,不小心将年龄设置成了小于1的数值(当前一般不会这种问题),这里只是做了一个模拟而已,那么我们就可以针对这种情况来做一些个处理。
如前面介绍所知,出现了异常,本质上了new了一个异常对象,异常对象中保存了可能会出现问题的类型和内容、位置等等信息
我们通常的操作是:
// 实现了Exception类,并重写其中的两个方法而已
public class MyException extends Exception {
public MyException() {
}
public MyException(String message) {
super(message);
}
}
8、编译工具控制台异常分析
通常编译工具中,比如我用的idea中常常会爆出一连串的异常。那么一连串的异常解决,首先是定位到异常的根源,然后逐一向上定位问题出现的问题。
用一个例子来进行表示:
public class ExceptionOne {
public static void main(String[] args) {
ExceptionOne exceptionOne = new ExceptionOne();
exceptionOne.showDivision();
}
public void showArray(){
int[] arr = {1,2,3};
// 输出第四个元素
System.out.println(arr[4]);
}
public void showDivision(){
int in = 1/0;
showArray();
}
}
控制台输出:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.guang.exceptiondemo.ExceptionOne.showDivision(ExceptionOne.java:16)
at com.guang.exceptiondemo.ExceptionOne.main(ExceptionOne.java:6)
Process finished with exit code 1
控制台会显示在栈中方法的调用过程。main线程种的exceptionOne对象调用了showDivision,在showDivision方法又调用了showArray方法。其实这两个方法中都有异常,但是因为是运行期异常,我都没有来进行处理。那么导致了在调用了showDivision方法的时候,出现了异常,又没有声明异常和进行处理,导致了线程中断,那么既然已经中断了,很明显,showArray就调用不到了。
所以控制台出现了很多异常,直接从最下面来找问题,然后逐一向上来查找问题。从上面的代码中可以看到,即使showDivision出现了问题修复后,再次启动会再次报错,那么还得按照上面的思路来找问题,知道问题解决完毕。
9、思考
要知道为什么有异常?出现了异常如何去快速定位问题出现的原因?对于不知道如何处理异常的方法如何处理???
10、总结
程序出现了问题并不可怕,可怕的不知道如何定位到问题并解决问题。
编程体现不了一个程序员的技术水平,但是解决bug却可以体现出一个程序员的综合素质。