面试题:Java必知必会:异常机制详解 背1
一、Java异常概述
在Java中,所有的事件都能由类描述,Java中的异常就是由java.lang包下的异常类描述的。
Trowable是所有异常的超类. 他的常用方法printStackTrece()打印异常信息.
Error 代表程序处理的错误. 通过程序改变不了的 . Java运行时系统的内部错误和资源耗尽错误。
1、Throwable(可抛出):异常类的最终父类,它有两个子类,Error与Exception。
Throwable中常用方法有:
getCause():返回抛出异常的原因。如果 cause 不存在或未知,则返回 null。
getMeage():返回异常的消息信息。
printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段 System.err 的值。
2、Error(错误):表示程序无法处理的错误,一般与程序员的执行操作无关。理论上这些错误是不允许发生的,如果发生,也不应该试图通过程序去处理,所以Error不是try-catch的处理对象,而JVM一般的处理方式是终止发生错误的线程。Error类常见子类有VirtualMachineError与AWTError。
3、VirtualMachineError(虚拟机错误):表示虚拟机出现错误。
在Java运行时内存中,除程序计数器外的虚拟机栈、堆、方法区在请求的内存无法被满足时都会抛出OutOfMemoryError;
而如果线程请求的栈深度超出虚拟机允许的深度时,就会抛出StackOverFlowError。
4、AWTError(AWT组件出错):这个错误并不是很常用。但是提一下AWT与Swing的区别,AWT是使用操作系统中的图形函数的抽象窗口工具,用C\C++编写,为了实现Java“一次编译,处处运行”的理念,AWT使用各个操作系统图形函数的交集,所以功能较差,但运行速度较快,适合嵌入式Java;
而Swing组件是基于AWT编写的图形界面系统,它用纯Java编写,所以必然实现了“一次编译,处处运行”,但相较于AWT运行速度较慢,适合PC使用。
5、Exception(异常):出现原因取决于程序,所以程序也理应通过try-catch处理。
异常分为两类:可查异常与不可查异常。
编译期异常:编译器要求必须处理,否则不能通过编译,使用try-catch捕获或者throws抛出。常见的可查异常有IOException(IO错误)及其子类EOFExcption(文件已结束异常)、FileNotFound(文件未找到异常)。
运行时(也叫运行时异常):编译期不会检查,所以在程序中可不处理,但如果发生,会在运行时抛出。所以这类异常要尽量避免!常见的不可查异常都是RuntimeException类及其子类。
1’ NullPointerException:空指针异常。调用了不存在的对象或未经实例化或初始化的对象时会抛出,如当试图操作一个空对象(赋值为null)的属性、方法时就会抛出。
(实例化:通俗的理解就是为对象开辟空间,使其可在规定范围内被调用。注意:User u;这只是一个对象声明,并没有进行实例化或初始化。
初始化:就是把实例化后的对象中的基本数据类型字段赋默认值或设定值,为非基本类型赋值null,对于static字段只会初始化一次。)
2’ ArithmeticException:算术条件异常。最常见的就是0作除数时会抛出。
3’ ClassNotFoundException:类未找到异常。在通过反射Class.forName(“类名”)来获取类时,如果未找到则会抛出异常。
4’ ArrayIndexOutOfBoundsException:数组索引越界异常。当试图操作数组的索引值为负数或大于等于数组大小时会抛出。
5’ NegativeArraySizeException:数组长度为负值异常。一般在初始化数组大小为负值时抛出。
6’ ArrayStoreException:数组类型不匹配值异常。例如将一个Object数组中加入一个Integer对象与一个String对象时,类型不匹配就会抛出。
7’ IllegalArgumentException:非法参数异常。会在使用Java类库方法时传入参数值越界时抛出。
二、异常处理
Java中的异常处理原则:必须声明抛出异常或捕获可查异常,允许忽略Error与不可查异常。
public class TestException {
public static void main(String[] args)
throws IOException{ //抛出可查IO异常
//throw是针对对象抛出的异常,throws是针对方法抛出的异常
FileWriter fileWriter = new FileWriter("output.txt");
String str = null; //str对象未经初始化
try {
fileWriter.write(str); //尝试调用未经初始化的str对象,会抛出空指针异常
} catch (NullPointerException e) {
System.out.println("Catch NullPointerException!");
}finally{
str = "finally!";
fileWriter.write(str);
fileWriter.close();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
执行结果: -
控制台:
Catch NullPointerException!
output.txt:
finally!
1、throws意为抛出,只要出现异常,就会创建对应异常对象,然后记录异常时运行状态等异常信息,交付给运行时系统处理。
抛出异常是一定执行在捕获之前的,没有抛出就不会有捕获。程序可以显式使用throws来声明抛出可查异常以通过编译。
2、try-catch-finally异常捕获语句:
try中是可能发生异常的程序段;
catch中依次编写对应的异常处理器方法,当抛出异常后,由运行时系统在栈中从当前位置开始依次回查方法,
直到找到合适的异常处理方法,如果3w3t未找到,则执行finally或直接结束程序运行。
finally :无论是否捕获或处理异常,finally块里的语句都会被执行。
注意(很重要,面试常问):当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。
在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中抛出了异常且未处理。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)CPU出现异常被关闭。
3、try-catch-finally的执行顺序
1’当没有异常捕获时,会跳过catch,直接执行finally块。
public class TestException {
public static void main(String[] args){
try {
System.out.println("Hello world!");
} catch (NullPointerException e) {
System.out.println("Catch NullPointerException!");
}catch (ArithmeticException e) {
System.out.println("Catch ArithmeticException!");
}catch(Exception e){
System.out.println("Catch other Exception!");
}
finally{
System.out.println("Finally!");
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
输出结果:
Hello world!
Finally!
2’ 当抛出运行时异常且没有定义相应的异常处理方法,就会由JVM抛出异常。
public class TestException {
public static void main(String[] args){
String str = null;
int a = 2, b = 0;
//调用空对象的方法,会抛出空指针异常
System.out.println(str.length());
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
输出结果:
Exception in thread “main” java.lang.NullPointerException
at Java面试.TestException.main(TestException.java:11)
3、当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,最后执行finally语句块后的语句。
public class TestException {
public static void main(String[] args){
String str = null;
int a = 2, b = 0;
try {
//调用空对象的方法,会抛出空指针异常
System.out.println(str.length()); //语句1
//除数为0,会抛出数学运算错误
System.out.println("a/b=" + a/b); //语句2
} catch (NullPointerException e) {
System.out.println("Catch NullPointerException!");
}catch (ArithmeticException e) {
System.out.println("Catch ArithmeticException!");
}catch(Exception e){
System.out.println("Catch other Exception!");
}
finally{
System.out.println("Finally!");
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
输出结果:
Catch NullPointerException!
Finally!
三、自定义一个异常类
通过继承Exception类实现。
class MyException extends Exception { // 创建自定义异常类
String message; // 定义String类型变量
public MyException(String ErrorMessagr) { // 父类方法
message = ErrorMessagr;
}
public String getMessage() { // 覆盖getMessage()方法
return message;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
四、异常链与异常栈轨迹
public class TestException {
public static void main(String[] args){
TestException test = new TestException();
String str = null;
test.printStringMessage(str);
}
public void printStringMessage(String str){
System.out.println(str.length());
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
Exception in thread “main” java.lang.NullPointerException
at Java面试.TestException.printStringMessage(TestException.java:16)
at Java面试.TestException.main(TestException.java:12)
常规异常:有Java所定义的异常,不需要异常声明,在未被try-catch的情况下,会被默认上报到main()方法。
异常的冒泡上传机制:当一个异常对象产生了以后,其会按照调用层次(一般是方法的调用层次)进行冒泡,直到被try-catch处理,或上报至main()方法。
//自定义的异常类
public class MyException extends Exception{
String message; // 定义String类型变量
public MyException(String ErrorMessagr) { // 父类方法
message = ErrorMessagr;
}
public String getMessage() { // 覆盖getMessage()方法
return message;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
//测试异常链、冒泡机制
public class TestException {
void firstThrow()
throws MyException { //抛出自定义异常
System.out.println("Oringinally creat a MyException and throw it out");
throw new MyException("MyException"); //真正的抛出异常处
}
void secondThrow()
throws MyException { //抛出自定义异常
firstThrow(); //调用firstThrow()
}
public TestException()
throws MyException { //构造方法,抛出自定义异常
secondThrow(); //调用secondThrow()
}
public static void main(String[] args) {
try{
//调用构造方法
TestException testException=new TestException();
}
catch(MyException e)
{
e.printStackTrace();
System.out.println("Catch a my exception!");
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
输出结果:
Oringinally creat a MyException and throw it out
Java面试.MyException: MyException
at Java面试.TestException.firstThrow(TestException.java:11)
at Java面试.TestException.secondThrow(TestException.java:16)
at Java面试.TestException.(TestException.java:20)
at Java面试.TestException.main(TestException.java:26)
Catch a my exception!
从异常栈的记录信息可以发现,与代码相对应的异常抛出机制和次序:
firstThrow()产生MyException对象->异常冒泡至调用其的secondThrow()->冒泡至调用secondThrow()的TestExceptionChain的构造方法->冒泡至printtry的main()方法。
注意到:异常对象一直被抛出,直至在printtry的mian()方法中被try-catch捕获!
面试题:Java必知必会:异常机制详解 背1的更多相关文章
- 转 Java虚拟机5:Java垃圾回收(GC)机制详解
转 Java虚拟机5:Java垃圾回收(GC)机制详解 Java虚拟机5:Java垃圾回收(GC)机制详解 哪些内存需要回收? 哪些内存需要回收是垃圾回收机制第一个要考虑的问题,所谓“要回收的垃圾”无 ...
- Java核心知识体系3:异常机制详解
1 什么是异常 异常是指程序在运行过程中发生的,由于外部问题导致的运行异常事件,如:文件找不到.网络连接失败.空指针.非法参数等. 异常是一个事件,它发生在程序运行期间,且中断程序的运行. Java ...
- Java必知必会:异常机制详解
一.Java异常概述 在Java中,所有的事件都能由类描述,Java中的异常就是由java.lang包下的异常类描述的. 1.Throwable(可抛出):异常类的最终父类,它有两个子类,Error与 ...
- Java 虚拟机系列二:垃圾收集机制详解,动图帮你理解
前言 上篇文章已经给大家介绍了 JVM 的架构和运行时数据区 (内存区域),本篇文章将给大家介绍 JVM 的重点内容--垃圾收集.众所周知,相比 C / C++ 等语言,Java 可以省去手动管理内存 ...
- 面试题:Java开发中的23种设计模式详解(转)
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- Java虚拟机5:Java垃圾回收(GC)机制详解
哪些内存需要回收? 哪些内存需要回收是垃圾回收机制第一个要考虑的问题,所谓“要回收的垃圾”无非就是那些不可能再被任何途径使用的对象.那么如何找到这些对象? 1.引用计数法 这个算法的实现是,给对象中添 ...
- Java垃圾回收(GC)机制详解
一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收.除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此.所以,垃圾回收是必须的. 二. ...
- Java垃圾回收【GC】机制详解
一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收.除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此.所以,垃圾回收是必须的. 二. ...
- Java核心知识1:泛型机制详解
1 理解泛型的本质 JDK 1.5开始引入Java泛型(generics)这个特性,该特性提供了编译时类型安全检测机制,允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,即给类型指定一个参 ...
随机推荐
- [leetcode]_Validate Binary Search Tree
题目:判断一棵二叉树是否合法.要求二叉树满足 左子树所有值 < 当前值 < 右子树所有值,并且所有点都满足这个条件. 思路: 1.从当前根节点判断,求根节点左子树最大值maxLeft,右子 ...
- hibernate正向工程生成数据库
hibernate正向工程生成数据库 hibernate.cfg.xml ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 2 ...
- (转)Makefile经典教程(掌握这些足够)
该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客: http://blog.csdn.net/haoel/article/details/2886 makefile很重 ...
- juc线程池原理(六):jdk线程池中的设计模式
一.jdk中默认线程池中的代理模式 单例类线程池只有一个线程,无边界队列,适合cpu密集的运算.jdk中创建线程池是通过Executors类中提供的静态的方法来创建的,其中的单例类线程池的方法如下: ...
- Vue.js:目标结构
ylbtech-Vue.js:目标结构 1.返回顶部 1. Vue.js 目录结构 上一章节中我们使用了 npm 安装项目,我们在 IDE(Eclipse.Atom等) 中打开该目录,结构如下所示: ...
- mongdb与mysql的联系和区别
与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精确值. ...
- mysql字符类型
字符类型 #官网:https://dev.mysql.com/doc/refman/5.7/en/char.html #注意:char和varchar括号内的参数指的都是字符的长度 #char类型:定 ...
- 小记一次mysql启动失败没有日志的处理
本来mysql好的,之前清理了一次tmp下的东西,mysql在查询的时候提示: Can't create/write to file '/tmp/ib0n3frL 然后停止启动: [root@sevc ...
- 实验吧CTF题库-WEB题(部分)
看起来有点难 提交admin http://ctf5.shiyanbar.com/basic/inject/index.php?admin=admin&pass=admin&actio ...
- SQL Server专题
SQL Server 2005/2008 一.连接异常 在C#代码中调用Open()方法打开数据库连接时(账户为sa),出现异常:异常信息如下: 在与 SQL Server 建立连接时出现与网络相关的 ...