文章链接:https://blog.csdn.net/m0_55746113/article/details/135473445?spm=1001.2014.3001.5502
什么是异常?
指的是程序在执行过程中,出现的非正常情况,如果不处理最终会导致JVM的非正常停止。(逻辑上的错误不算)
异常的抛出机制
Java中把不同的异常用不同的类表示,一旦发生某种异常,就创建该异常类型的对象
,并且抛出(throw
)。
然后程序员可以捕获(catch
)到这个异常对象,并处理;如果没有捕获(catch
)这个异常对象,那么这个异常对象将会导致程序终止。
如何对待异常
对于程序出现的异常,一般有两种解决方法:
一是遇到错误就终止程序的运行。另一种方法是程序员在编写程序时,就充分考虑到各种可能发生的异常和错误,极力预防和避免。实在无法避免的,要编写相应的代码进行异常的检测、以及异常的处理
,保证代码的健壮性
。
异常的体系结构
java.lang.Throwable
:异常体系的根父类 (它的父类是Object)
java.lang.Error
:错误。(基本不做处理)
java.lang.Exception
:异常。
我们可以编写针对性的代码进行处理。
编译时异常:(受检异常) 在执行javac.exe
命令时,出现的异常。(这一章的异常处理针对的就是它)
运行时异常:(非受检异常) 在执行java.exe
命令时,出现的异常。(基本不做处理)
ArrayIndexOutOfBoundsException (数组越界–用非法索引访问数组时抛出的异常)
NullPointerException (空指针异常)
ClassCastException (类转换异常)
NumberFormatException (数据格式化异常)
InputMismatchException (输入类型不一致)
ArithmeticException (算术异常)
文章链接:https://blog.csdn.net/m0_55746113/article/details/135547506?spm=1001.2014.3001.5502
try-catch-finally
try{
...... //可能产生异常的代码
}
catch( 异常类型1 e ){
...... //当产生异常类型1型异常时的处置措施
}
catch( 异常类型2 e ){
...... //当产生异常类型2型异常时的处置措施
}
finally{
...... //无论是否发生异常,都无条件执行的语句
}
catch中异常处理的方式:
① 自己编写输出的语句。
② printStackTrace():打印异常的详细信息。 (推荐)
③ getMessage():获取发生异常的原因。
try中声明的变量,出了try结构之后,就不可以进行调用了。
try-catch结构是可以嵌套使用的。
对于运行时异常:
开发中,通常就不进行显示的处理了。
一旦在程序执行中,出现了运行时异常,那么就根据异常的提示信息修改代码即可。
对于编译时异常:
一定要进行处理。否则编译不通过。
5.2 什么样的代码我们一定要声明在finally中呢?
我们在开发中,有一些资源(比如:输入流、输出流,数据库连接、Socket连接等资源),在使用完以后,必须显式的进行关闭操作,否则,GC不会自动的回收这些资源。进而导致内存的泄漏。
为了保证这些资源在使用完以后,不管是否出现了未被处理的异常的情况下,这些资源能被关闭。我们必须将这些操作声明在finally中!
6.面试题
final 、 finally 、finalize 的区别
文章链接:https://blog.csdn.net/m0_55746113/article/details/135618390?spm=1001.2014.3001.5502
throws 异常类型1,异常类型2,...
"public void test() throws 异常类型1,异常类型2,.. {
//可能存在编译时异常 (运行时异常不用管它)
}
throws
)。方法的重写的要求:(针对于编译时异常来说的)
子类重写的方法抛出的异常类型可以与父类被重写的方法抛出的异常类型相同,或是父类被重写的方法抛出的异常类型的子类。
开发中,如何选择异常处理的两种方式?(重要、经验之谈)
try-catch-finally
来处理,保证不出现内存泄漏。try-catch-finally
进行处理,不能throws。(父类没有throws,子类也不能throws)throws
,而方法a中通常选择使用try-catch-finally
。文章链接:https://blog.csdn.net/m0_55746113/article/details/135656358?spm=1001.2014.3001.5502
为什么需要手动抛出异常对象?
在实际开发中,如果出现不满足具体场景的代码问题,我们就有必要手动抛出一个指定类型的异常对象。
如何理解"自动 vs 手动"抛出异常对象?
过程1:“抛”
“自动抛” : 程序在执行的过程当中,一旦出现异常,就会在出现异常的代码处,自动生成对应异常类的对象,并将此对象抛出。
“手动抛” :程序在执行的过程当中,不满足指定条件的情况下,我们主动的使用"throw + 异常类的对象"方式抛出异常对象。
过程2:“抓”
狭义上讲:try-catch的方式捕获异常,并处理。
广义上讲:把“抓”理解为“处理”。则此时对应着异常处理的两种方式:① try-catch-finally ② throws
如何实现手动抛出异常?
在方法内部,满足指定条件的情况下,使用"throw 异常类的对象
"的方式抛出。
注意点:throw后的代码不能被执行,编译不通过。
面试题:throw 和 throws 的区别? “上游排污,下游治污”
文章链接:https://blog.csdn.net/m0_55746113/article/details/135678410?spm=1001.2014.3001.5502
如何自定义异常类?
① 继承于现有的异常体系。通常继承于RuntimeException
\ Exception
② 通常提供几个重载的构造器
③ 提供一个全局常量,声明为:static final long serialVersionUID
如何使用自定义异常类?
🌋题目描述:Java的异常体系简单介绍下(网*)
包含问题:
> 异常的顶级接口是什么(软**力) 答:Throwable类
> 异常类的继承关系,exception下都有哪些类?(上海*冉信息)
🍰答
java.lang.Throwable
:异常体系的根父类 (它的父类是Object)
java.lang.Error
:错误。(基本不做处理)
java.lang.Exception
:异常。
我们可以编写针对性的代码进行处理。
编译时异常:(受检异常) 在执行javac.exe
命令时,出现的异常。(这一章的异常处理针对的就是它)
运行时异常:(非受检异常) 在执行java.exe
命令时,出现的异常。(基本不做处理)
🌋题目描述:Java异常处理机制(*科软)
🍰答
两种处理方案:try-catch-finally
;throws
。
🌋题目描述:异常的两种类型,Error和Exception的区别(上海冠*新创、北京中**译、*度)
🍰答
①Error:错误。Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。一般不编写针对性的代码进行处理。
②Exception:异常。我们可以编写针对性的代码进行处理。
🌋题目描述:运行时异常与一般异常有何异同?(华*思为)
🍰答
运行时异常:RuntimeException
一般异常:Exception
🌋题目描述:说几个你常见到的异常(华油**普)
类似问题:
> 请列出Java中常见的几种异常?(百*园)
> 给我一个你最常见到的runtime exception。(*蝶)
🍰答
①开发1-2年:
②开发3年以上:
OOM
🌋题目描述:说说final、finally、finalize的区别(北京中**译、艾软件、拓思、*科软)
类似问题:
> finally和final的区别(*科软)
🍰答
final:最终的
finally:try-catch-finally中必须要被执行的代码
finalize:方法名,任何一个类直接或间接继承于Object,不重写的话不会用这个方法。当这个类的对象要被GC回收的时候,在回收之前的遗言写在这里面,就是当前类的对象要调用的方法。在jdk9之后被标记为过时的方法了。
🎲注
关于finalize,在这一篇博客里面:https://blog.csdn.net/m0_55746113/article/details/134389583?spm=1001.2014.3001.5502
如下:
🌋题目描述:如果不使用try-catch,程序出现异常会如何?(上海冠*新创科技)
🍰答
对于当前方法来讲,如果不使用try-catch
,则在出现异常对象以后会抛出此对象。
如果没有处理方案,就会终止程序的执行。(throws
不会在根本处解决问题)
🌋题目描述:try … catch捕捉的是什么异常?(北京亿*东方)
🍰答
Exception。非Error
🌋题目描述:如果执行finally代码块之前,方法返回了结果或者jvm退出了,这时finally块中的代码还会执行吗?(恒*电子)
🍰答
方法返回了结果:finally会执行。
JVM退出了:finally一般会执行;特别的,System.exit(0);
(强制结束)此时finally不会执行。
🌋题目描述:在try语句中有return语句,最后写finally语句,finally语句中的code会不会执行?何时执行?如果执行是在return前还是后(拓*思、华**为)
🍰答
方法是一个栈帧,放在栈里面。栈帧又分为好几个部分,有局部变量表(存放局部变量)、操作数栈(用来临时存放数据)。
比如:
public static void main(String[] args) {
int result = test("a");
System.out.println(result);
}
public static int test(String str) {
try {
Integer.parseInt(str);
return 1;
} catch (NumberFormatException e) {
return -1;
} finally {
System.out.println("test结束");
}
}
当我们执行return -1
的时候,它会将-1
放入操作数栈里面,按道理说下一步应该将-1
拿出去,方法就结束了。但是此时先不能拿出去,需要先执行finally
里面的语句,执行完之后再把-1
拿出去。
所以return -1
这里有两个过程,第一个过程是将-1放入操作数栈里面,第二个过程是将-1拿出去。在这两个过程中间,插入了finally的语句。
finally中的语句会执行。整体来看,是finally先;但是细节来看,是return先,再finally,最后再return。
🌋题目描述:捕获异常在catch块里一定会进入finally吗?catch里能return吗?catch里return还会进finally吗?在try里return是什么情况?(*蓝)
🍰答
会;可以;会;return之前要先执行一下finally。(finally一定会被执行的)
🌋题目描述:throw和throws的区别?(北京亿**方、北京新*阳光)
🍰答
角度1:“形”,即使用的格式
throw
:使用在方法内部,“throw 异常类的对象
”throws
:使用在方法的声明处,“throws 异常类1,异常类2,...
”角度2:"角色"或作用不同
上游排污,下游治污。
throw
:手动将异常抛出,相当于生成一个异常对象(所谓的自动抛,只不过不是我们自己写的代码而已,源码里面也是用throw关键字来写的)try-catch
(根本解决)throws
:对异常对象的一种处理,抛向该方法的调用方法🌋题目描述:子类重写父类抛出异常的方法,能否抛出比父类更高级别的异常类(顺*)
🍰答
不能!
子类重写父类抛出异常的方法,只能和父类抛出异常一样或者这个异常的子类。
🌋题目描述:如何自定义一个异常?(*软国际)
🍰答
① 继承于现有的异常体系。通常继承于RuntimeException
\ Exception
② 通常提供几个重载的构造器
③ 提供一个全局常量,声明为:static final long serialVersionUID