前段时间集合的整理真的是给我搞得心力交瘁啊,现在可以整理一些稍微简单一点的,搭配学习 ~

突然想到一个问题,这些东西我之前就整理过,现在再次整理有什么区别嘛?我就自问自答一下,可能我再次整理会看到不一样的一面,会从源码和整体来看。其次,之前的整理都是在某个地方止步,可持续性较差,现在就尽力坚持住。因为还有你们再看 ~ 另外,欢迎各行各业的同学们给我投稿,让大家都能互相了解,岂不是很棒!

进入正题,看看 Java 中的异常处理。当程序执行的时候没有按照我们的意思执行,发生了一些不可言语的 bug 时,你打算怎么搞?不管不问,还是主动出击,而 Java 语言为此就准备了一套处理异常的类。

Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。

两个子类,Error 和 Exception,通常用于指示发生了异常情况。通常,这些实例是在异常情况的上下文中最新创建的,因此包含了相关的信息(比如堆栈跟踪数据)。Throwable 包含了其线程创建时线程执行堆栈的快照。还可以给出错误提示信息。

Error 及其子类表示的是错误,是 JVM 本身出错了,不能由程序控制,我们最主要就是看异常。

Exception 及其子类表示的是异常,异常又分为检查异常和非检查异常,这是在 javac 编译器的角度进行分类的,检查异常在我们编写代码的时候会提示出来,我们必须要对其进行处理,处理方式有两种,下面看。非检查时异常对应于上图中的 RuntimeException ,编译的时候不报错,在运行的时候才会出现。

在 Java 中处理异常有两种思路,自己解决掉,干净利索或是抛给方法的调用者,就像你有事会找警察一样,当然警察不一定能给你解决,就像是你抛出的异常可能会被再次抛出去一样。最终会抛给 JVM ,然后程序挂掉。

自己处理主要是使用 try { } catch ( ) { } finally { } 语句块,使用 try 包裹可能出现异常的代码,使用 catch 来捕获可能出现的异常。最后 finally 语句块是用来执行那些必须要执行的代码,比方说释放资源文件,关闭数据库连接等操作。

有几点需要说明一下:

1 可以有多个 catch 语句块,但是捕获异常的顺序一定要注意,当异常出现时,只要被 catch 捕获,则下面的 catch 不再执行。所以我们要把范围小的异常种类或者说子类放在上面。

2 我们都听过 finally 语句块是一定会执行的,其实不是这样的,当遇到 system.exit() 就不会再执行了,因为你强制退出 JVM 了。除此之外,确实是一定执行的。

3 只有 catch 块才能处理异常,try 只是圈起范围的作用,而 finally 块是善后作用。

4 try catch finally 语句块中的变量都是局部变量,它们之间是不能共享的,待会看个例子。

另一种方式就是自己搞不定就使用 throws 抛出去,抛给方法的调用者,让它们去处理。在方法的声明中添加语句 throws ,即可将检查时异常抛出,后续的处理就留给方法的 caller 吧!

上面都是在检查异常发生时我们可以做的相应处理,若是运行时发生了异常,还有一种操作可以在代码执行的过程中手动的抛出一个异常,使用 throw 关键字,例如这样:

String name;
if(name == "null"){
throw new IllegalArgumentException("姓名不能为空");
}

因为异常的产生是会形成连锁反应,一旦有异常发生,所有的调用者都会发生异常,异常发生最开始的地方就是异常的抛出点,抛出点的异常会向 caller 转移。所以在方法的重写中,子类抛出的异常类型一定要小于或等于父类的抛出异常类型,不然,你想想,子类 throws 出去的异常太大,父类肯定接不住呀。

最后就是要看一个例子,来看一下 return 语句在语句块中的应用。加深一下对异常处理的理解。

class Test {
public int aaa() {
int x = 1; try {
return ++x;
} catch (Exception e) { } finally {
++x;
}
return x;
} public static void main(String[] args) {
Test t = new Test();
int y = t.aaa();
System.out.println(y);
}
}

问:最后打印 y 是多少 ? 执行的过程是怎么的 ?

结果是 2 ,过程却可能不是那么好解释,在 try 语句中我们执行 ++x 然后就直接返回 2 ? 肯定不是,因为还要执行 finally 语句块啊,所以 Java 规范规定,在存在 finally 块时,会将 try 中的 return 放在一边,而优先执行 finally 中的代码,但是已经得到的结果 2 可没有丢了,而是存在了 try 块中的本地变量表中,以备不时之需。

在执行 finally 块之后,x 等于 3 ,一样的还是会将 3 保存在 finally 块的本地变量表中,然后再回到 try 中进行 return 操作,此时,方法结束,返回的结果就是之前保存在 try 块本地变量表中的 2 。假如我们在 finally 块中也有 return 语句,就会返回 3 而不再执行 try 中的 return 语句,然而 Java 规范不希望我们这么做,因为 finally 语句块的主要作用是为了释放资源,关闭连接操作。

结合这个例子我们要明白,在每个语句块中都会存在一个本地表量表,会保存使用到变量的值,各个语句块是分离开的,所以在执行 return 语句的时候,返回的是本地变量表中的变量。

在 finally 块中使用 return 还有一个弊端,它会抑制 try 和 catch 中的异常的抛出。看下面例子,在 try 块中也是一样的。

public static void main(String[] args) {
int result;
try{
result = foo();
System.out.println(result); //输出100
} catch (Exception e){
System.out.println(e.getMessage()); //没有捕获到异常
}
//catch中的异常被抑制
@SuppressWarnings("finally")
public static int foo() throws Exception {
try {
int a = 5/0;
return 1;
}catch(ArithmeticException amExp) {
throw new Exception("我将被忽略,因为下面的finally中使用了return");
}finally {
return 100;
}
} //try中的异常被抑制
@SuppressWarnings("finally")
public static int bar() throws Exception {
try {
int a = 5/0;
return 1;
}finally {
return 100;
}
}

总结

return 语句代表方法结束,但是遇到 finally 语句块也是要等一等的。

无论 try 里执行了 return 语句、break 语句、还是 continue 语句,finally 语句块还会继续执行,除非遇上了 system.exit() 。

finally 中不建议使用 return 语句的,释放资源就好。

推荐阅读:

Java 集合之 Map

Java 集合之 Collection

String 的常用操作

Sting 与不可变对象

Java 中的异常的更多相关文章

  1. 【Java心得总结二】浅谈Java中的异常

    作为一个面向对象编程的程序员对于 下面的一句一定非常熟悉: try { // 代码块 } catch(Exception e) { // 异常处理 } finally { // 清理工作 } 就是面向 ...

  2. Java中的异常-Throwable-Error-Exception-RuntimeExcetpion-throw-throws-try catch

    今天在做一个将String转换为Integer的功能时,发现Integer.parseInte()会抛出异常NumberFormatException. 函数Integer.parseInt(Stri ...

  3. Java中的异常详解

    一.异常定义 阻止当前方法或作用域继续执行的问题,称为异常 二.异常分析      所有不正常类都继承Throwable类,这个类主要有两个子类Error类和Exception类.Error指系统错误 ...

  4. Java中的异常和处理详解

    简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函数返回值作为执行状态?. ...

  5. Java中的异常简介

    Java中异常的分类 Java中的异常机制是针对正常运行程序的一个必要补充,一般来说没有加入异常机制,程序也能正常运营,但是,由于入参.程序逻辑的严谨度,总会有期望之外的结果生成,因此加入异常机制的补 ...

  6. java中的异常类

    Java中的异常: 1. Throwable是所有异常的根,java.lang.Throwable Throwable包含了错误(Error)和异常(Exception),Exception又包含了运 ...

  7. Java 中的异常和处理详解

    Java 中的异常和处理详解 原文出处: 代码钢琴家 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误 ...

  8. Java 中的异常和处理详解(转载)

    原文出处: 代码钢琴家 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函 ...

  9. Java中的异常和处理详解(转发:https://www.cnblogs.com/lulipro/p/7504267.html)

    简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函数返回值作为执行状态?. ...

随机推荐

  1. [转载]bootstrap 2.3版与3.0版的使用区别

    http://www.weste.net/2013/8-20/93261.html bootstrap已经推出了3.0的新版,看起来2.3.x版本也不会再更新了.那么bootstrap 2.3版与3. ...

  2. 自己写的一个小的剪刀——石头——布游戏的GUI程序

    很简单的一个程序,建议各位初学Java的同学可以试试写写这个程序: import javax.swing.JOptionPane; public class Game { public static ...

  3. 【转】java格式化输出 printf 例子

    [转]java格式化输出 printf 例子 转自http://www.cnblogs.com/TankMa/archive/2011/08/20/2146913.html#undefined imp ...

  4. 【51nod】1766 树上的最远点对

    [题意]给定n个点的树,m次求[a,b]和[c,d]中各选出一个点的最大距离.abcd是标号区间,n,m<=10^5 [算法]LCA+树的直径理论+线段树 [题解] 树的直径性质:距离树上任意点 ...

  5. angular4 get,post请求(带参数,与不带参数)

    一:在app.module.ts引入HttpMoudle import { BrowserModule } from '@angular/platform-browser'; import { Htt ...

  6. Eclipse中如何调整字体

    Eclipse 字体有两处,一处是控制台的字体,一处是主窗口.这里分别介绍控制台和主窗口字体的调节方法. Window -> Preferences -> General -> Ap ...

  7. ORA 00972 错误处理

    Oracle 11G SQL 写好的脚本执行后报错:ORA 00972 标识符过长 可能的原因一: select 语句中的字段别名太长,中文字符别名最长为10个汉字,简化别名名称,问题得到解决. 可能 ...

  8. Java与JS生成二维码

    1.二维码概念 二维码/二维条码是用某种特定的集合图形按一定规律在平面上(二维方向上)分布的黑白相间的图形记录数据符号信息的图片. 黑线是二进制的1,空白的地方是二进制的0,通过1.0这种数据组合用于 ...

  9. gcc -O0 -O1 -O2 -O3 四级优化选项及每级分别做什么优化【转】

    转自:http://blog.csdn.net/qinrenzhi/article/details/78334677 相关博客http://blog.chinaunix.net/uid-2495495 ...

  10. Cloud Lab: 泰晓实验云台【转】

    转自:http://tinylab.org/cloud-lab/ 可快速构建的计算机课程在线实验平台 由 Wu Zhangjin 创建于 2017/10/06 评论 打赏 项目描述 泰晓实验云台 项目 ...