摘要:根据异常对象判断是否存在异常处理。否则,范围小的异常会因异常处理完成而无法处理。异常处理中使用作为异常的统一出口。
参考《第一行代码java》《java程序设计教程》
java中程序的错误有语法错误、语义错误。如果是语法性错误,在编译时就可以检查出来并解决。语义错误是在程序运行时出现的,在编译时没有错误,但在运行时可能会出现错误导致程序退出,这些错误称为异常。在没有异常处理的情况下,也即默认情况下,程序出现异常后会打印异常信息,同时终止执行异常之后的代码。为了让程序在出现异常后仍然可以正常执行完毕,必须引入异常处理语句完善代码。因此,异常处理机制用于检测和处理异常,提高java程序的健壮性。
在java中,所有的异常都当做对象处理,即当发生异常时产生了异常对象。java异常处理机制的语法为:
</>复制代码
try{
//可能出现异常的语句
}catch(异常类型 对象){
//异常处理
}finally{
//不管是否出现异常,仍会统一执行的代码
}
try语句用于捕获可能出现异常的代码。catch语句根据不同的异常类型进行不同的异常处理,因此一个try语句可以对应多个catch语句。如果try语句中产生异常,程序会跳转到匹配异常类型的catch语句中,进行异常处理。不管程序是否产生异常,都会执行finally语句。finally语句可以省略。如果省略了finally语句,程序在执行完catch语句后,会继续向下执行。
catch语句和finally语句可以省略,但是不能同时省略。异常格式的组合通常有如下三种:try...catch, try...catch...finally, try...finally。
在java中,所有异常类型最高继承类是Throwable。Throwable下面有两个子类Error和Exception。java的异常子类命名都会使用***Error或***Exception的形式,开发者可以根据这个特征进行区分Error和Exception。
Error是JVM错误,属于不可查错误。出现Error时程序因无法处理,没有执行。
Exception是程序运行中的错误,用户可以使用异常处理格式处理。异常分为可查异常和不可查异常。
不可查异常是在运行中出现的异常。这类异常在编译中可能出现,也可能不出现,所以在程序中可以选择处理这类异常,或者选择不处理。RuntimeException和其子类属于不可查异常。
可查异常是在编译时被强制检查的异常。这种异常可以预见,因此必须在程序中进行处理,或进行捕获和处理,或抛出给上一级调用方法处处理。否则,编译将无法通过。RuntimeException以外的异常都属于可查异常。
ArithmeticException:数学运算异常。
NullPointerException:空指针异常。
NegativeArraySizeException:数组大小为负值异常。
ArrayIndexOutOfBoundException:数组下标越界异常。
NumberFormatException:数字格式异常。
InputMismatchException:输入类型不匹配异常。
NoSuchMethodException:方法不存在异常。
DataFormatException:数据格式错误异常。
NoClassDefFoundError:未找到类定义错误。
OutOfMemoryError:内存不足错误。
StackOverflowError:堆栈溢出错误。
ThreadDeath:线程结束。
UnknownError:未知错误。
</>复制代码
public Throwable getCause() //返回Throwable对象的原因。
</>复制代码
public String getMessage() //返回Throwable对象的详细信息
</>复制代码
public void printStackTrace() //将此Throwable对象的堆栈跟踪输出至错误输出流,作为System.err的值
异常的处理流程
1、当程序出现异常,JVM自动根据异常的类型实例化一个与之类型匹配的异常类对象。
2、根据异常对象判断是否存在异常处理。如果不存在异常处理,则由JVM对异常默认处理:输出异常信息,结束程序调用。
3、如果存在异常捕获操作,try语句捕获异常类实例化对象,再与catch语句进行异常类型匹配,并处理异常。
4、不管是否匹配到catch语句,如果存在finally语句,就会执行finally语句代码。
5、finally语句后面的代码根据之前是否匹配到catch语句进行处理。如果匹配到catch语句,也即捕获到异常,则继续执行finally后的语句。如果没有匹配到catch语句,则将异常交由JVM默认处理。
异常捕获是一个异常类对象的传递过程,所有异常类对象都可以相父类对象转型。因此可以异常类对象可以使用Exception接收,简单实现异常处理。
对于异常分开处理还是一起处理的问题,没有严格的规范,而是根据项目开发标准决定。异常分开处理便于代码的维护,统一处理则可以节省开发精力。
在处理多个异常时,范围小的异常要放在范围大的异常之前处理。否则,范围小的异常会因异常处理完成而无法处理。
throws关键字用在方法的定义上,表示此方法不进行异常的处理,而是交给被调用处处理。
</>复制代码
myMath.java
class myMath{
public static int div(int x, int y) throws Exception{ //该方法不处理异常
return x/y;
}
}
exception_throws.java
public class exception_throws{
public static void main(String args[]){
try{ //div()方法抛出异常,这里必须明确处理异常
System.out.println(myMath.div(10,0));
}catch(Exception e){
e.printStackTrace();
}
}
}
throw关键字
throw关键字用于用户手动抛出一个异常类实例化对象。
</>复制代码
exception_throw.java
public class exception_throw{
public static void main(String args[]){
try{
throw new Exception("self-defined exception"); //直接抛出自定义异常类对象
}catch(Exception e){
e.printStackTrace();
}
}
}
异常处理的标准格式
除在上面提到的三种异常组合格式,还有一种是try...catch...finally结合throw和throws的异常处理格式。
</>复制代码
class myMath{
public static int div(int x, int y) throws Exception{ //出现异常交给被调用处输出
System.out.println("===start===");
int result = 0;
try{
result = x / y;
}catch(Exception e){
throw e; //向上抛出
}finally{
System.out.println("===end===");
}
return result;
}
}
public class exception_standerd{
public static void main(String args[]){
try{
System.out.println(myMath.div(10,0)); //被调用处处理异常
}catch(Exception e){
e.printStackTrace();
}
}
}
在本例中,也可以将myMath.java中的catch语句省略。myMath.java中的try语句捕获的异常通过div()方法抛出给调用处处理。
RuntimeException类RuntimeException的子类对象可以根据用户需要进行有选择的处理,程序在编译时不会强制性要求用户处理异常,所以在调用时不处理也不会有任何编译错误。如果没有处理却发生异常,则交给JVM默认处理。
例如Integer类中的parseInt()方法
</>复制代码
public static int parseInt(String s) throws NumberFormatException;
异常类NumberFormatException属于RuntimeException子类。使用parseInt()时可根据需要处理Runtime子类异常。
</>复制代码
public class exception_RuntimeException{
public static void main(String args[]){
int temp = Integer.parseInt("100");
System.out.println(temp);
}
}
assert关键字
assert在JDK1.4时候引入的,通常用于程序不准备使用捕获异常来处理的错误。其功能是在程序执行到某行后,判断是否是预期的结果。断言的语法格式:
</>复制代码
assert 布尔表达式
</>复制代码
assert 布尔表达式:字符串表达式
java默认没有开启断言功能。因此程序正式执行时不用去除断言语句。在执行解释java字节码文件时,增加参数“-ea”,开启断言功能。
</>复制代码
java -ea exception_assert
</>复制代码
public class exception_assert{
public static void main(String args[]){
int num = 10;
assert num == 20 : "num isn"t 20";
System.out.println("num = " + num);
}
}
自定义异常
当java提供的异常类型不能满足开发需要时,可以自己开发一个异常类。实现自定义异常类,只需要继承Exception或RuntimeException父类即可。
</>复制代码
class AddException extends Exception{
public AddException(String msg){
super(msg);
}
}
public class exception_selfdefine{
public static void main(String args[]){
int num = 20;
try{
if(num > 10){
throw new AddException("value is too large!");
}
}catch(Exception e){
e.printStackTrace();
}
}
}
练习
填空
1、 Throwable下有哪两个子类: 。
2、 ArthmeticException类表示 异常,ArraysIndexOutOfBoundsException表示 异常。
3、 一个try代码后面必须跟着若干个 代码段或者一个 代码段。
4、 如果一个方法使用了 ,则编译器会强制在使用此方法时进行异常的处理。
5、 异常处理中使用 作为异常的统一出口。
选择
1、 使用那个关键字可以在程序中手工抛出异常 。
</>复制代码
A、 throws B、 throw C、 assert D、 class
2、 下面 关键字可以用在方法的声明处?
</>复制代码
A、 throws B、 assert C、 class D、 interface
3、 为了捕获一个异常,代码必须放在下面 语句块中。
</>复制代码
A、 try块 B、 catch块 C、 throws块 D、 finally块
4、 下面关于try块的说法正确的是 。
</>复制代码
A、 try块后至少应有一个catch块 B、 try块后必须有finally块
C、 可能抛出异常的方法应放在try块中 D、 对抛出的异常的处理应放在try块中
5、 finally块中的代码将 。
</>复制代码
A、 总是被执行
B、 如果try块后面没有catch块时,finally块中的代码才会执行
C、 异常发生时才被执行
D、 异常没有发生时才执行
6、 一个异常将终止 。
</>复制代码
A、 整个程序 B、 只终止抛出异常的方法
C、 产生异常的try块 D、 上面的说法都不对
7、 所有异常的共同父类是 。
</>复制代码
A、 Error B、 Exception C、 Throwable D、 RuntimeException
判断
1、 一个try语句后有多个catch时,捕获范围大的异常要放在捕获范围小的异常之后。 ( )
2、 finally语句可以根据需要有选择的添加。 ( )
简答
1、 简述RuntimeException和Exception的区别。
2、 try、catch、finally三种语句的功能是什么?
3、 简述Java中的异常处理机制。
4、 简述Error和Exception的区别。
5、 列举三个常见的RuntimeException子类。
编程
1、 编写应用程序,从命令行输入两个小数参数,求它们的商。要求程序中捕获NumberFormatException异常和ArithmeticException异常。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/76910.html
摘要:目录介绍问题汇总具体问题好消息博客笔记大汇总年月到至今,包括基础及深入知识点,技术博客,学习笔记等等,还包括平时开发中遇到的汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善开源的文件是格式的同时也开源了生活博客,从年 目录介绍 00.Java问题汇总 01.具体问题 好消息 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技...
摘要:运行时数据区域的学习,是学习以及机制的基础,也是深入理解对象创建及运行过程的前提。了解内存区域划分,是学习概念的前提。 Java 运行时数据区域的学习,是学习 jvm 以及 GC 机制的基础,也是深入理解 java 对象创建及运行过程的前提。废话不多说,直接进入正题: 一张图总结 showImg(https://segmentfault.com/img/bVOMAn?w=685&h=5...
摘要:当多个线程对同一个集合的内容进行操作时,就可能会产生事件。当某一个线程遍历的过程中,的内容被另外一个线程所改变了就会抛出异常,产生事件。在线程在遍历过程中的某一时刻,线程执行了,并且线程删除了中的节点。 概要 前面,我们已经学习了ArrayList。接下来,我们以ArrayList为例,对Iterator的fail-fast机制进行了解。 1 fail-fast简介 fail-fast...
阅读 1378·2023-04-25 19:10
阅读 1232·2021-09-10 10:50
阅读 3112·2021-09-02 15:21
阅读 1464·2019-08-30 15:52
阅读 1759·2019-08-30 13:56
阅读 2210·2019-08-30 12:53
阅读 1953·2019-08-28 18:22
阅读 2205·2019-08-26 13:47