全面理解java异常机制
在理想状态下,程序会按照我们预想的步骤一步一步的执行,但是即使你是大牛,你也不可避免出错,所以java为我们提供了异常机制。本文将会从以下几个方面介绍java中的异常机制:
- 异常机制的层次结构
- 异常的处理过程
- 抛出异常
- 捕获异常
- 异常机制的实现细节
一、异常机制的层次结构
在java程序设计语言中,所有的异常对象都是派生于Throwable类,一般情况下,如果java中内置的异常类不能满足需求,可以自定义异常类只需要继承与Throwable类即可,下面是java 中的异常层次结构:
error类表示java内部错误,例如jvm出错或者内存不足等,这层一般不用我们关心(其实我们也无可奈何,如果出现此种问题),一旦出现此种错误程序会自动结束。
我们主要还是需要研究Exception类及其子类,Exception主要有两个子类,IOException和RuntimeException我们一个个看。IOException是IO错误类问题导致的异常,是可预知的,例如由于文件不存在而打开文件失败引起的异常等。RuntimeException类异常表示运行时异常,例如数组下标越界,访问空指针等,是不可预知的,但是这类异常于编写程序时应当予以避免,例如你可以使用if(a==null).....,加以检查避免。
以上从一种角度对这些主要的异常类进行了分类,其实我们还有一种分类方式,按照是否是检查类异常(checked)进行分类,什么是检查类异常?检查类异常(checked)就是指编译器会检查当前的代码块中,判断是否有这么一条语句在程序执行时可能产生异常,如果有就会建议程序员处理。(实际上你必须处理,不然编译不会通过),在以上的分层中,error类和RuntimeException类属于非检查异常类(unchecked),而IOException属于检查类异常。
二、异常的处理过程
public class Test2 {
public static void main(String[] args){
doMaths();
}
public static void doMaths(){
int a = 10/0;//此处将会出现异常
System.out.println(a);
}
}
输出结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at test.Test2.doMaths(Test2.java:8)
at test.Test2.main(Test2.java:5
相信大家在看完上文之后,可以判断出此处的异常应该属于RuntimeException,属于unchecked异常,由输出的结果可以看出:main方法中调用方法doMaths();,于是进入该方法内部,执行int a = 10/0;产生异常,在本方法中未找到处理,于是返回调用处(即main函数中),发现main函数中依然没有处理方法,于是执行默认操作(打印异常信息)。
我们的程序难免会出现问题,但是绝对不能让用户看出来你的程序出现问题,所以这些异常信息是绝对不能让用户看见的,且不说他是否能看懂,一旦遇到“行家”,你的程序就会存在安全隐患,由此可见,对异常的处理是多么重要。下面我们将讨论两种处理异常的机制。
三、抛出异常
以下所讨论的处理异常的方法,主要还是针对检查类异常(checked),因为对于error类的错误我们没法处理,对于RuntimeException类异常我们应当尽量在程序中加以避免,所以我们主要还是对检查类异常进行处理。
我们使用关键字throws将本程序中可能遇到的异常向上抛出(向调用出抛出,让调用者处理),而本身不做处理。
public void test() throws AppException{
................
...............
}
throws 紧跟方法的括号后面,这个叫异常的声明表示本方法不处理这个异常,谁调用我这个方法谁来处理(后面将讨论如何处理异常,因为总要有人来处理,否则就默认打印异常信息),可以声明多个异常,异常之间使用逗号相隔。
那么throw关键字和throws关键字究竟有什么联系呢?throw可以理解为是在throws关键字的主动行为。先看代码:
public class Test2 {
public static void main(String[] args){
show();
}
public static void show(){
String s = null;
s.charAt(0);
}
}
/*以上代码抛出NullPointerException,空指针异常*/
public static void show() throws NullPointerException{
String s = null;
s.charAt(0);
}
/*你可以选择抛给调用者*/
public static void show(){
String s = null;
if(s==null){
throw new NullPointerException();
}
s.charAt(0);
}
/但是如果你可以判断s处可能出现异常,就可以主动抛出异常*/
小结一下,throws关键字表示:本函数中存在某个异常但是我不知道,如果出现此异常就抛给调用者。throw一般和判断语句if配合的多表示:如果满足条件就结束此函数并向调用者抛出异常,否则就继续执行接下来的代码。
**四、捕获异常**
以上说了那么多,我们知道如何将遇到的异常抛出,让别人处理,但是总是有人需要处理这个异常的,总不能让系统默认的将异常信息打印出来吧!再者说,一个strong的程序必须要有对错误的处理,让程序控制在手中而不是莫名卡死或者退出。接下来,我们一起探讨如何捕获异常对他进行处理。
捕获异常,我们使用try{}catch{}关键字,try中代码表示可能出现异常的代码块,catch中的代码块表示捕捉到该异常之后需要进行的后续操作。
/*使用上述代码,添加try catch捕获异常*/
public class Test2 {
public static void main(String[] args){
try{
show();//可能出现异常的代码块
}catch(NullPointerException z){
System.out.println("throw Exception");
//捕捉到异常后的操作
}
}
public static void show()throws NullPointerException {
//将异常抛给调用者
String s = null;
s.charAt(0);
}
}
输出结果:
throw Exception
对比于之前,打印自己控制的内容是不是比默认打印异常信息更加的友好?我们常常会遇到这么一个问题:打开一个文件,准备对文件进行操作,但是在对文件的操作过程中出现异常,退出程序了,但是文件并没有被显式的关闭,造成资源浪费。
我们常常使用关键字finally来完成类似这样的操作。finally关键字紧跟catch后面,表示无论是否发生异常都会执行的代码块。finally不是必须的可以没有。
try{
//可能出现异常的代码块
}catch{
//捕获异常之后的代码块
}finally{
//肯定要执行的代码块
}
**五、异常机制的实现细节**
第一个我想说的是try{}catch{}这种结构并不是唯一的,可以由多个catch语句的,对多个不同的异常进行捕获。
第二个很重要的finally这个关键字中如果出现return等关键字程序的接下来的执行顺序问题。例如:
try{
int a=0;
//出现异常
return a;
}catch(..){
a=1;
return a;
}finally{
a=2;
return a;
}
程序返回:2;
能想明白么?其实不难,只要知道finally语句块中是最后执行的就可以理解了,当try中出现异常,被catch接住,将a赋值为1,在返回之前跳转到finally语句块中,最后在finally语句块中返回2,这种在finally语句块中有return语句的会阻止catch中的return执行。
所以,我们建议finally语句块中不要使用return语句。
**以上便是java异常机制的基本内容,如果错误,望大家指出。tk**
全面理解java异常机制的更多相关文章
- Java基础 -- 深入理解Java异常机制
异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通 过API中Throwable类的众多子类描述各种不同的异常. ...
- 理解Java类加载机制(译文)
理解java类加载机制 你想写类加载器?或者你遇到了ClassCastException异常,或者你遇到了奇怪的LinkageError状态约束异常.应该仔细看看java类的加载处理了. 什么是类加载 ...
- 深入理解java异常【绝对经典,推荐最少看五遍】
http://blog.csdn.net/hguisu/article/details/6155636 补充:检查异常(checkedException)与运行异常,什么时候throw,什么时候thr ...
- 【转】深入理解java异常处理机制
深入理解java异常处理机制 ; int c; for (int i = 2; i >= -2; i--) { c = b / i; System.out.println("i=&qu ...
- Java异常机制及异常处理建议
1.Java异常机制 异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通过API中Throwable类的众多子类 ...
- [Java学习笔记] Java异常机制(也许是全网最独特视角)
Java 异常机制(也许是全网最独特视角) 一.Java中的"异常"指什么 什么是异常 一句话简单理解:异常是程序运行中的一些异常或者错误. (纯字面意思) Error类 和 Ex ...
- 从零开始理解JAVA事件处理机制(2)
第一节中的示例过于简单<从零开始理解JAVA事件处理机制(1)>,简单到让大家觉得这样的代码简直毫无用处.但是没办法,我们要继续写这毫无用处的代码,然后引出下一阶段真正有益的代码. 一:事 ...
- 从零开始理解JAVA事件处理机制(3)
我们连续写了两小节的教师-学生的例子,必然觉得无聊死了,这样的例子我们就是玩上100遍,还是不知道该怎么写真实的代码.那从本节开始,我们开始往真实代码上面去靠拢. 事件最容易理解的例子是鼠标事件:我们 ...
- Java 异常机制
Java 异常机制 什么是异常 异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程 为什么要有异常 什么出错了 哪里出错了 ...
随机推荐
- LearningDocker--Chapter3--Building images
This chapter is quite different from the earlier ones, and it is in this chapter to clearly describe ...
- HDU 3501 Calculation 2 ——Dirichlet积
[题目分析] 卷积太有趣了. 最终得出结论,互质数和为n*phi(n)/2即可. 计算(n*(n+1)/2-n-n*phi(n)/2)%md,用反正法即可证明. [代码] #include <c ...
- WCF应用场景
WCF全称Windows Communication Foundation,是Microsoft为构建面向服务的应用提供的分布式通信编程框架,是.NET Framework 3.5的重要组成部分.使用 ...
- shell 创建带参数的命令方法
主要用到case in,和shift命令. shift 命令是从参数数组中,删除当前第一个参数. while [ "$1" != "" ] do case $1 ...
- 谈谈字符集编码及gb2312、utf-8编码原理
一.基础中的基础比特位即bit,是计算机最小的存储单位.以0或1来表示比特位的值.Byte是字节数,bit是位数,在计算机中每八位为一字节,也就是1Byte=8bit:Byte和bit都翻译成比特,俗 ...
- sql相关语言
SQL 掌握一门编程语言: C C++ Java C# ... 数据库 数据结构/算法 链表 队列 栈 数组 面向对象 网络 (界面.业务逻辑) 关系型数据库: 以二维表的形式组织数据 表.索引.视图 ...
- kafkaspout以及kafkabolt的最简实例
这个实例中有一个KafkaSpout,一个KafkaBolt,一个自定义Bolt QueryBolt.数据流程是KafkaSpout从topic为recommend的消息队列中取出St ...
- YII 1.0 (7) 登录信息调取 session使用
登陆信息调取 Yii::app()->user->name,调取登陆的session信息 登录时 调用了 $LoginForm->login() 这个方法上面就能够取到登录的用户名 ...
- Sublime Text3 常用快捷键动画演示及优秀插件分享
Sublime Text 是前端的一个神器,以其精简和可DIY而让广大fans疯狂.好吧不吹了直入正题 -_-!! 首先是安装,如果你有什么软件管家的话搜一下就好,一键安装.然后,有钱的土豪就自己买个 ...
- gdb命令整理
Microsoft Windows XP [版本 ] (C) 版权所有 - Microsoft Corp. C:\Documents and Settings\Administrator>e: ...