运行时异常和编译异常
1.概念:
Java中将程序执行中发生的不正常情况称为异常(Exception)
2.分类
- Error(错误):JVM无法解决的严重问题,程序会崩溃,比如JVM系统内部错误、资源耗尽等
- Exception:因编程错误等外在因素导致的一般性问题,可以使用针对性代码进行处理,如空指针访问、网络连接中断等,Exception可以分为两大类:
- 运行时异常:编译器检测不出,是
java.lang.RuntimeException
类及其子类,一般是指编程时的逻辑错误,可以不作处理(不做处理不是说不会报错),若全部处理可能会影响代码的可读性和运行效率- 编译时异常:编译器要求必须处置的异常,否则代码不能通过编译
- 异常体系图:
3.常见运行时异常
NullPointerException
:空指针异常,当应用程序试图在需要对象的地方出现null时抛出该异常ArithmeticException
: 数学运算异常,当出现异常的运算条件时抛出此异常ArrayIndexOutOfBoundsException
: 数组下标越界异常,用非法索引访问数组时抛出的异常ClassCastException
:类型转换异常,当试图将对象强制转换为不是实例的子类时抛出该异常NumberFormatException
:数字格式不正确异常,当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时抛出该异常
4.常见编译异常
SQLException
:操作数据库时查询表可能发生的异常
IOException
:操作文件时发生的异常
FileNotFoundException
:操作不存在文件时发生的异常
ClassNotFoundException
:加载类而类不存在时发生的异常
EOFException
:操作文件到文件末尾发生异常
IllegalArguementException
:参数异常
5.异常处理
概念:当异常发生时对异常处理的方式
处理方式:
try-catch-finally
:程序员在代码中捕获发生的异常并自行处理try {// 可能有异常的代码 }catch (Exception e){// 1.异常发生时将异常封装为Exception e传递给catch// 2.得到该对象后程序员自己处理// 3.如果没有发生异常catch代码块不执行 }finally {// 不管try代码块是否发生异常都要执行finall代码块// 一般用于释放资源// 可以只有try-catch部分 }
- 异常发生后,异常部分后面的代码不会执行(不是必须将try代码块全部执行,而是try代码块中发生异常后面的代码不会执行)而是直接进入到catch代码块,注意
try-catch
代码块后面的代码还是会执行(除非未正确捕获或者在catch代码块中return了):try {String str = "psj";int a = Integer.parseInt(str);System.out.println(a); // 该行代码不会执行 } catch (NumberFormatException e) {e.printStackTrace(); } System.out.println("程序继续..."); // 这一行代码还是会执行
- 可以有多个catch语句,但是父类异常在后,子类异常在前。如果发生异常只会匹配一个catch:
try {String str = "psj";int a = Integer.parseInt(str);System.out.println(a); } catch (NumberFormatException e) {e.printStackTrace(); // 执行该代码块 } catch (Exception e) {e.printStackTrace(); // 不会再去执行该代码块 }
try-finally
配合使用相当于没有捕获异常,所以如果出现异常会抛出异常,并没有自己处理,然后执行finally代码块
throws
:如果方法可能发生某种异常但是无法确定如何处理该异常,可以将发生的异常抛出并交给方法的调用者处理,最顶级的处理者为JVM:public static void test() throws FileNotFoundException {FileInputStream f = new FileInputStream("psj.txt"); }
- throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类
- throws后面可以是一个异常列表
try-catch-finally
和throws
二选一- 程序员没有显示处理异常,默认使用
throws
抛出异常
注意事项:
编译异常必须处理,即显示使用
throws
或try-catch
对于运行时异常,如果程序没有处理默认是throws方式处理
子类重写父类方法时,抛出的异常类型要么和父类抛出的一致,要么为父类抛出异常类型的子类
自定义异常:程序中的错误信息没有出现在Throwable子类中描述处理,此时需要自己设计异常类用于描述该错误信息
- 定义类:异常类继承
Exception
或RuntimeException
(继承Exception
属于编译异常,继承RuntimeException
属于运行异常),一般继承RuntimeException
(因为编译异常必须要处理)int age = 180; //要求范围在 18 – 120 之间,否则抛出一个自定义异常 if(!(age >= 18 && age <= 120)) {//通过构造器设置信息throw new AgeException("年龄需要在 18~120 之间"); } System.out.println("你的年龄范围正确."); //-----------自定义异常类------------ class AgeException extends RuntimeException{public AgeException(String message) {System.out.println(message);} }
throw和throws的区别:
意义 位置 后面跟的东西 throws 异常处理的一种方式 方法声明处 异常类型 throw 手动生成异常对象的关键字 方法体中 异常对象 try {if (args.length != 4){// 该行代码生成一个异常,因为try代码块中出现异常,所以又去执行catch代码块throw new ArrayIndexOutOfBoundsException("参数个数不对"); } } catch (ArrayIndexOutOfBoundsException e) {System.out.println(e.getMessage()); }
tips:
为什么
try-catch-finally
外的代码还可以执行?因为使用异常捕获的目的就是为了让程序继续正常执行(但是出现异常时try中的代码不能再继续往下执行)既然
try-catch
外的代码块在出现异常后依旧可以执行,为什么还需要finally代码块?因为catch并不能保证一定能捕获到正确的异常,会导致后续代码无法执行:try {String str = "psj";int a = Integer.parseInt(str);System.out.println(a); } catch (ArrayIndexOutOfBoundsException e) { // 异常捕获错误,这里是类型转换异常却捕获的是数组越界e.printStackTrace(); } System.out.println("程序继续...");
- try/catch代码块中如果有return语句,还是会去执行finally代码块,如果finally中有return语句就执行finally的return语句,没有就执行try/catch代码块中的return语句(假设try-catch-finally中try-catch中都有return语句,不出现异常时执行try中的,出现异常就执行catch中的):
System.out.println("执行test方法后,i=" + test()); //--------------test方法-------------- public static int test() {int i = 0;try {String str = "psj";int a = Integer.parseInt(str);return i;} catch (NumberFormatException e) {return ++i; // 执行++i后i=1,但是不会执行return,而是必须执行finally代码块} finally {++i; // 这个i是上面++i后的i值,所以该步++i后变为2System.out.println("执行finally代码块后,i=" + i);return 3} } // 最后结果: 执行finally代码块后,i=2 执行test方法后,i=3
- 由于声明代码块中的变量为局部变量,所以声明在try中的变量不能在catch和finally中使用,反之亦然(比如在JDBC中会把需要关闭的对象在try-catch-finally代码块外先声明并赋值null)
- 在
finally
代码块中有return
语句了就不能再在try-catch-finally
外加上return
语句,因为finally
代码块中的return
语句是必须执行的。如果有try-catch
中都有return
语句,此时也不能在try-catch-finally
外加上return
语句
运行时异常和编译异常相关推荐
- 22.Java之异常处理(异常介绍,异常体系图一览,运行时异常,编译异常,try-catch方式处理异常,throws异常处理,自定义异常,throws 和 throw 的区别)
22.1.异常介绍 Java语言中,将程序执行中发生的不正常情况称为 "异常" (开发过程中的语法错误和逻辑错误不是异常) 执行过程中所发生的异常事件分为两大类: Error:Ja ...
- 11.2运行异常和编译异常
异常体系 ------------|Throwable(super类) ----------------|Error(错误) ----------------|Exception(异常) ------ ...
- 什么是引发?Java运行时系统引发的异常如何处理?
到目前为止,你只是获取了被Java运行时系统引发的异常.然而,程序可以用throw语句引发明确的异常.Throw语句的通常形式如下: throw ThrowableInstance; 这里,Throw ...
- java编译时多态和运行时多态_运行时多态、编译时多态和重载、重写的关系(不区分Java和C#,保证能看懂!)...
以前在大学学习OOP的时候,知道了重载和重写的区别,但如果要把他们和多态联系起来,我想很多新手朋友和我当初一样是死记的,可是时间长了,自然而然就忘记了,最近在写测试的时候,终于"开窍&quo ...
- java多态编译,java多态 运行时多态和编译时多态
java多态 运行时多态和编译时多态 我们知道java的多态是一个重要的特性,其中体现java的多态有两种形式.运行时的多态和编译时的多态. 编译时的多态会发生在方法重载的时候,方法的重载指方法名相同 ...
- C++-运行时类型信息,异常(day11)
一.运行时类型信息 1.typeid运算符 头文件:#include<typeinfo> C++的标准头文件,都对应相应的类 //sizeof(类型/变量/表达式),返回内存大小 type ...
- 动态so库的链接:运行时链接和编译时链接
在编写Makefile时,如果一个程序需要链接so库,则需要通过两个步骤来完成,分为运行时动态库的链接和编译时动态库的链接,缺一不可. 1.运行时动态库的链接 在执行可执行文件时,提示: error ...
- c++ 多态 运行时多态和编译时多态_C++学习笔记之多态
多态是面向对象三大特性之一 多态分为两类: 静态多态:函数重载 和 运算符重载 属于静态多态,复用函数名 动态多态:派生类 和 虚函数 实现运行时多态 静态多态和动态多态的区别: 静态多态的函数地址早 ...
- c++多态之 运行时多态与编译时多态
多态的定义: 同一操作作用与不同的对象,可以有不同的解释,产生不同的执行结果. (1)编译时多态/静态联编 指联编工作在编译阶段完成,即在编译阶段确定了程序中的操作调用与执行该操作的代码间的关系,基于 ...
最新文章
- linux进程间通信:system V消息队列
- android studio串号,AndroidStudio使用常见问题集锦
- dubbo源码分析(3)
- 力扣删除排序数组中的重复项 II
- [转]leo谈“80后”程序员为什么找不到工作?(1)
- 用linux集成电路版图设计,集成电路版图设计报告.doc
- C/C++ OpenCV图像的载入,显示,输出
- SQL Server 2000订阅与发布的具体操作
- 计算机英语讲课笔记(2020-6-23)
- oxm java_使用JAXB2.0实现OXM
- 命令netstat和DHCP
- Ubuntu16.04使用时的一些问题总结
- 整数输入问题一百二十九:阿基米德特性
- 软考中级-软件设计师|下午题攻略
- 南开hpd openbilibili
- 静夜思 | 你的眼界,决定了你发现美好的能力
- 如何保持积极的心态?
- 通过Java实现求水仙花数
- rss源_如何在Windows桌面上显示RSS源
- [NOI2005]瑰丽华尔兹 动态规划 + 单调队列