潍坊Java培训
达内潍坊中心

17343065216

热门课程

Java异常处理基础

  • 时间:2019-06-21
  • 发布:潍坊java培训
  • 来源:潍坊java培训

在 程序设计 和 运行 的 过程中, 发生 错误 是 不可避免 的。 尽管 Java 语言 的 设计 从根本上 提供 了 便于 写出 整洁、 安全 的 代码 的 方法, 并且 程序员 也 尽量 地 减少 错误 的 产生, 但 使 程序 被迫 停止 的 错误 的 存在 仍然 不可避免。 为此, Java 提供 了 异常 处理机 制 来 帮助 程序员 检查 可能 出现 的 错误, 保证 了 程序 的 可读性 和 可维护性。 Java 中将 异常 封装 到 一个 类 中, 出现 错误 时, 就会 抛出 异常。

Java异常处理基础

异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。

比如说,你的代码少了一个分号,那么运行出来结果是提示是错误java.lang.Error;如果你用System.out.println(11/0),那么你是因为你用0做了除数,会抛出java.lang.ArithmeticException的异常。

异常发生的原因有很多,通常包含以下几大类:

用户输入了非法数据。

要打开的文件不存在。

网络通信时连接中断,或者JVM内存溢出。

这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。-

要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:

检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。

运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。

错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

有 许多 异常 的 例子, 如 空 指针、 数组 溢出 等。 Java 语言 是一 门面 向 对象 的 编程 语言, 因此, 异常在 Java 语言 中 也是 作为 类 的 实例 的 形式 出现 的。 当某 一 方法 中 发生 错误 时, 这个 方法 会 创建 一个 对象, 并且 把 它 传递 给 正在 运行 的 系统。 这个 对象 就是 异常 对象。 通过 异常 处理 机制, 可以 将 非 正常 情况下 的 处理 代码 与 程序 的 主 逻辑 分离, 即在 编写 代码 主 流程 的 同时 在 其他 地方 处理 异常。

Exception类的层次

所有的异常类是从java.lang.Exception类继承的子类。

Exception类是Throwable类的子类。除了Exception类外,Throwable还有一个子类Error 。

Java程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。

Error用来指示运行时环境发生的错误。

例如,JVM内存溢出。一般地,程序不会从错误中恢复。

异常类有两个主要的子类:IOException类和RuntimeException类。

Exception类的层次

捕获异常

Java 语言 的 异常 捕获 结构 由 try、 catch 和 finally 3 部分 组成。 其中, try 语句 块 存放 的 是 可能发生 异常 的 Java 语句; catch 程序 块 在 try 语句 块 之后, 用来 激发 被 捕获 的 异常; finally 语句 块 是 异常 处理 结构 的 最后 执行 部分, 无论 try 语句 块 中的 代码 如何 退出, 都将 执行 finally 语句 块。

try{

// 程序 代码 块

} catch( Exceptiontype1 e){

// 对 Exceptiontype1 的 处理

} catch( Exceptiontype2 e){

// 对 Exceptiontype2 的 处理

} …

finally{

// 程序 块

}

通过 异常 处理器 的 语法 可知, 异常 处理器 大致 分为 try- catch 语句 块 和 finally 语句 块。

可能 出现 异常 的 代码 用 try- catch 语句 块 进行 处理, 当 try 代码 块 中的 语句 发生 异常 时, 程序 就会 调转 到 catch 代码 块 中 执行, 执行 完 catch 代码 块 中的 程序 代码 后, 将 继续 执行 catch 代码 块 后的 其他 代码, 而 不会 执行 try 代码 块 中 发生 异常 语句 后面 的 代码。 由此 可知, Java 的 异常 处理 是 结 构化 的, 不会 因为 一个 异常 影响 整个 程序 的 执行。

注意:

Exception 是 try 代码 块 传递 给 catch 代码 块 的 变量 类型, e 是 变量 名。 catch 代码 块 中 语句“ e. getMessage();” 用于 输出 错误 性质。 通常, 异常 处理 常用 以下 3 个 函数 来 获取 异常 的 有关 信息。

getMessage() 函数: 输出 错误 性质。

toString() 函数: 给出 异常 的 类型 与 性质。

printStackTrace() 函数: 指出 异常 的 类型、 性质、 栈 层次 及 出现 在 程序 中的 位置。

多重捕获块

一个try代码块后面跟随多个catch代码块的情况就叫多重捕获。

多重捕获块的语法如下所示:

try{ // 程序代码 }catch(异常类型1 异常的变量名1){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }

上面的代码段包含了3个catch块。

可以在try语句后面添加任意数量的catch块。

如果保护代码中发生异常,异常被抛给第一个catch块。

如果抛出异常的数据类型与ExceptionType1匹配,它在这里就会被捕获。

如果不匹配,它会被传递给第二个catch块。

如此,直到异常被捕获或者通过所有的catch块。

finally 语句 块

完整 的 异常 处理 语句 一定 要 包含 finally 语句, 无论 程序 中有 无异 常 发生, 并且 无论 之间 的 try- catch 是否 顺利 执行 完毕, 都会 执行 finally 语句。

在 以下 4 种 特殊 情况下, finally 块 不会 被 执行:

在 finally 语句 块 中 发生了 异常。

在前 面的 代码 中 使用 了 System. exit() 退出 程序。

程序 所在 的 线程 死亡。

关闭 CPU。

使用 throws 关键字 抛出 异常

若 某个 方法 可能 会 发生 异常, 但不 想在 当前 方法 中 处理 这个 异常, 则 可以 使用 throws、 throw 关键字 在 方法 中 抛出 异常。

throws 关键字 通常 被 应用 在 声明 方法 时, 用来 指定 方法 可能 抛出 的 异常。 多个 异常 可使用 逗号 分隔。

使用 throws 关键字 将 异常 抛 给 上 一级 后, 如果 不想 处理 该 异常, 可以 继续 向上 抛出, 但 最终 要有 能够 处理 该 异常 的 代码。

注意:

如果 是 Error、 RuntimeException 或 它们 的 子类, 可以 不 使用 throws 关键字 来 声明 要 抛出 的 异常, 编译 仍能 顺利 通过, 但在 运行时 会被 系统 抛出。

throw 关键字 通常用于 方法 体中, 并且 抛出 一个 异常 对象。 程序 在 执行 到 throw 语句 时 立即 终止, 它 后面 的 语句 都不 执行。 通过 throw 抛出 异常 后, 如果 想在 上一 级 代码 中 来 捕获 并 处理 异常, 则需 要在 抛出 异常 的 方法 中 使用 throws 关键字 在 方法 的 声明 中 指明 要 抛出 的 异常; 如果 要 捕捉 throw 抛出 的 异常, 则 必须 使用 try- catch 语句 块。

注意下面事项:

catch不能独立于try存在。

在try/catch后面添加finally块并非强制性要求的。

try代码后不能既没catch块也没finally块。

try, catch, finally块之间不能添加任何代码。

异常简单例子:

public class ClassText {

public static void main(String[] args) {

int textArray[] = new int[3];//用于测试数组越界异常的数组

int j;//用来使数组月结的下标

try {

for ( j = 0; j < (textArray.length + 1); j++) {//有+1可见 该测试一定越界

textArray[j] = (int) Math.random()*10 ;

}

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

}

System.out.println("但是上面抛出异常后 程序并没有直接结束 "

+ "而是跳出try()catch()语句 正常执行本条输出语句");

}

}

输出如下:

可以看到,发生异常后依然执行了后面的输出语句。

输出

很多初学者一直把throw / throws 语句,看作两种不同的异常处理方法,其实他们可以看作一个整体,throw语句可以看作异常的处理语句,而throws我们则可以将其类比为‘extends' ,它的主要作用是声明该方法(体内存在throw语句的方法,需要throws或者说我们可以看作需要‘继承/链接',该异常类型的原型),举个例子:

private static void textThrow_Throws(int radius) throws Exception {

if ( radius < 0 ) {//如果半径小于0 则不符合常理进行异常处理

throw new Exception();

}

}

这样一来throw/throws 的用法就显而易见了。

但是在写完throw/throws 语句后,异常处理并没有结束,因为这里只是简单声明了,我的这个成员方法中的可能会抛出异常,并没有写具体该如何处理这个异常,所以这是在主函数中,就要用try()catch()将他们包围。描述好具体的处理异常方法:完整测试代码如下:

public class ClassText {

public static void main(String[] args) {

int radius ;//定义一个叫做搬进的变量作为测试

radius = -5;//常理可知半径使正数

try {

textThrow_Throws(radius);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println("程序正常结束~");

}

private static void textThrow_Throws(int radius) throws Exception {

if ( radius < 0 ) {//如果半径小于0 则不符合常理进行异常处理

throw new Exception();

}

}

}

我们再看看输出:

范例输出

自定义异常类

自定义异常处理类,包括两部分:

(1)、类的构造方法,构造方法的建立则非常简单,其实只要继承父类(比如 Exception类 )的构造方法即可。

(2)、重写toString()函数,这是最重要的一点,再toString函数中,描述具体发生了什么错误导致了异常的抛出。这样一来用户才知道究竟是发生了什么错误。

这里结合throw/throws 举个例子:

首先自定义一个异常类:

public class ArrayIndexException extends Exception{

public ArrayIndexException() {

// TODO Auto-generated constructor stub

super();

}

@Override

public String toString() {

// TODO Auto-generated method stub

return"程序发生了越界异常! 请检查下标变化!";

}

}

Java异常处理基础

如上所示就是一个最基本的自定义异常类 ,它继承了Exception 并且重写了构造方法以及toString方法。

在主函数中调用它:

public class ClassText {

public static void main(String[] args) {

int textArray[] = new int[3];//用于测试数组越界异常的数组

try {

textSetArray(textArray);//调用下方数组赋值方法

} catch (ArrayIndexException e) {

// TODO: handle exception

e.printStackTrace();//如果发生了异常 则抛出自定义数组越界异常

}

System.out.println("go on !");

for(int j = 0 ; j < textArray.length ; j++ )

System.out.print(textArray[j] + " ");//再越界之前的数成功赋值

}

private static void textSetArray(int[] textArray) throws ArrayIndexException{

for ( int j = 0; j < (textArray.length + 1); j++) {//有+1可见 该测试一定越界

textArray[j] = 5 ;//给数组原属赋值

}

}

}

以上就是坊java培训班给大家做的内容详解,更多关于IT的学习,请继续关注坊java培训班

上一篇:全网最详细的Java 自动内存管理机制及性能优化教程!
下一篇:Java编程 初级、中级、高级提升各需要什么书

马上预约七天免费体验课

姓名:

电话:

深入探讨 Java 类加载器,你了解多少呢

Java架构—细说Spring——AOP详解

Java编程 初级、中级、高级提升各需要什么书

Java异常处理基础

选择城市和中心
贵州省

广西省

海南省

达内教育

有位老师想和您聊一聊