Java 异常的捕获与处理详解(二)

(一)、throws关键字

  throws关键字主要是在定义上使用的,表示的是此方法中不进行异常处理,而交给被调用处处理。

  例如:

1 class MyMath {
2     public int div(int x, int y) throws Exception {
3         return x / y;
4     }
5 }

  现在div()方法之中抛出一个异常出来,表示所有异常交给被调用处进行处理。

 1 class MyMath {
 2     public int div(int x, int y) throws Exception {
 3         return x / y;
 4     }
 5 }
 6
 7 public class Test {
 8     public static void main(String args[]) {
 9         try {
10             System.out.println(new MyMath().div(10, 0));
11         } catch (Exception e) {
12             e.printStackTrace();
13         }
14     }
15 }

运行结果:

1 java.lang.ArithmeticException: / by zero
2     at MyMath.div(Test.java:3)
3     at Test.main(Test.java:10)

注意:在调用throws关键字声明方法的时候,一定要使用异常处理操作进行异常的处理,这属于强制性的处理。

而主方法本身也属于方法,那么在主方法上也可以继续使用throws进行异常的抛出:

 1 class MyMath {
 2     public int div(int x, int y) throws Exception {
 3         return x / y;
 4     }
 5 }
 6
 7 public class Test {
 8     public static void main(String args[]) throws Exception {
 9         System.out.println(new MyMath().div(10, 0));
10     }
11 }

运行结果:

1 Exception in thread "main" java.lang.ArithmeticException: / by zero
2     at MyMath.div(Test.java:3)
3     at Test.main(Test.java:9)

这时主方法将异常继续向上抛,交给JVM进行异常的处理,也就是采用默认的方式,输出异常信息,而后结束程序执行。

注意:在实际开发中,主方法不要加throws,因为程序如果有异常,我们也希望可以正常的结束。

(二)throw关键字

  之前所有异常类的对象都是由JVM自动进行实例化操作的,用户自己也是可以手工地抛出一个异常类实例化对象,就通过throw完成了。

1 public class Test {
2     public static void main(String args[]) {
3         try {
4             throw new Exception("自定义的异常");
5         } catch (Exception e) {
6             e.printStackTrace();
7         }
8     }
9 }

运行结果:

1 java.lang.Exception: 自定义的异常
2     at Test.main(Test.java:4)

小结:throw和throws的区别?

  (1)throw: 在方法体内使用,表示人为地抛出一个异常类对象(这个对象可以是自己实例化的,也可以是已经存在的)

  (2)throws: 在方法的声明上使用,表示此方法中不进行异常的处理,而交给被调用处处理。

(三)、异常处理标准格式

我们有种感觉,finally和throw没有用处。现要求定义一个div()方法,这个方法有如下的一些要求: 
(1)在进行除法操作之前,输出一行提示信息; 
(2)在除法操作执行完毕后,输出一行提示信息; 
(3)如果中间产生了异常,则应该交给被调用处来进行处理。

 1 class MyMath {
 2     // 出现异常要交给被调用处出,使用throws
 3     public int div(int x, int y) throws Exception {
 4         System.out.println("===== 计算开始 =====");
 5         int result = 0;
 6         try {
 7             result = x / y; // 除法计算
 8         } catch (Exception e) {
 9             throw e; // 向上抛
10         } finally {
11             System.out.println("===== 计算结束 =====");
12         }
13         return result;
14     }
15 }
16
17 public class Test {
18     public static void main(String args[]) {
19         try {
20             System.out.println(new MyMath().div(10, 0));
21         } catch (Exception e) {
22             e.printStackTrace();
23         }
24     }
25 }

运行结果:

1 ===== 计算开始 =====
2 ===== 计算结束 =====
3 java.lang.ArithmeticException: / by zero
4     at MyMath.div(Test.java:7)
5     at Test.main(Test.java:20)

以上代码也可以做一些简化:

 1 class MyMath {
 2     // 出现异常要交给被调用处出,使用throws
 3     public int div(int x, int y) throws Exception {
 4         System.out.println("===== 计算开始 =====");
 5         int result = 0;
 6         try {
 7             result = x / y; // 除法计算
 8         } finally {
 9             System.out.println("===== 计算结束 =====");
10         }
11         return result;
12     }
13 }
14
15 public class Test {
16     public static void main(String args[]) {
17         try {
18             System.out.println(new MyMath().div(10, 0));
19         } catch (Exception e) {
20             e.printStackTrace();
21         }
22     }
23 }

运行结果:

1 ===== 计算开始 =====
2 ===== 计算结束 =====
3 java.lang.ArithmeticException: / by zero
4     at MyMath.div(Test.java:7)
5     at Test.main(Test.java:18)

直接使用try…finally,不带有catch,那么就连处理的机会都没有了,所以不建议使用try…finally。标准格式是try…catch、finally、throws、throw一起使用。

(四)、RuntimeException类

  先来观察一段代码

1 public class Test {
2     public static void main(String args[]) {
3         String str = "123";
4         int num = Integer.parseInt(str);
5         System.out.println(num * num);
6     }
7 }

运行结果:

1 15129

这个程序就是将一个字符串变为了基本数据类型,而后执行乘法操作,但是下面来看一下parseInt()方法定义:

1 public static int parseInt(String s) throws NumberFormatException

发现这个方法上抛出了一个NumberFormatException的异常,按照之前所讲,如果存在了throws,则必须使用try…catch进行处理,可是现在却没有强制要求处理,这是为什么呢? 
来观察一下NumberFormatException的继承结构:

1 java.lang.Object
2    |- java.lang.Throwable
3       |- java.lang.Exception
4           |- java.lang.RuntimeException
5               |- java.lang.IllegalArgumentException
6                   |- java.lang.NumberFormatException

发现NumberFormatException属于RuntimeException的子类,而在Java之中明确规定:对于RuntimeException的异常类型,在编译的时候不会强制性的要求用户处理,用户可以根据需要有选择性的来进行处理,在开发之中,如果没有处理,那么出现异常之后将交给JVM默认进行处理。也就是说,RuntimeException的子异常类,可以由用户根据需要有选择性的来进行处理。

小结:RuntimeException和Exception的区别?请列举出几个常见的RuntimeException.

(1)RuntimeException是Exception的子类; 
(2)Exception定义了必须处理的异常,而RuntimeException定义的异常可以选择性的进行处理。

常见的RuntimeException: 
NumberFormatException、ClassCastException、NullPointerException、ArithmeticException、ArrayIndexOutOfBoundsException。

五、assert关键字(断言)

Java中断言指的是程序执行到某行之后,其结果一定是预期的结果,而在JDK 1.4之后增加了一个assert关键字。

两种语法形式: 
(1)形式一:

1 assert condition;

这里condition是一个必须为真(true)的表达式。如果表达式的结果为true,那么断言为真,并且无任何行动 
如果表达式为false,则断言失败,则会抛出一个AssertionError对象。这个AssertionError继承于Error对象。

(2)形式二:

1 asser condition:expr;

这里condition是和上面一样的,这个冒号后跟的是一个表达式,通常用于断言失败后的提示信息,说白了,它是一个传到AssertionError构造函数的值,如果断言失败,该值被转化为它对应的字符串,并显示出来。

使用断言:

1 public class Test {
2     public static void main(String args[]) {
3         int x = 10;
4         // 假设经过了若干操作
5         assert x == 30 : "x的内容不是30";
6         System.out.println(x);
7     }
8 }

默认情况下,Java之中的断言,不会在正常执行的代码中出现,如果要想启用断言,则应该增加-ea选项:

1 java -ea Test

运行结果:

1 Exception in thread "main" java.lang.AssertionError: x的内容不是30
2         at Test.main(Test.java:5)

(六)、自定义异常

在Java之中本身已经提供了大量的异常类型,但是在开发之中,这些异常类型还不能满足于开发的需要。所以在一些系统架构之中往往会提供一些新的异常类型,来表示一些特殊的错误,而这种操作就称为自定义异常类,而要想实现这种自定义异常类,那么可以让一个类继承Exception或RuntimeException。

 1 class MyException extends Exception { // 自定义异常类
 2     public MyException(String msg) {
 3         super(msg);
 4     }
 5 }
 6
 7 public class Test {
 8     public static void main(String args[]) throws Exception {
 9         throw new MyException("自己的异常类");
10     }
11 }

运行结果:

Exception in thread "main" MyException: 自己的异常类
    at Test.main(Test.java:9)

参考链接: http://blog.csdn.net/wei_zhi/article/details/52837635

原文地址:https://www.cnblogs.com/revel171226/p/8295580.html

时间: 2024-10-13 22:53:14

Java 异常的捕获与处理详解(二)的相关文章

Java 异常的捕获与处理详解 (一)

一,异常的产生(Exception) 异常是程序之中导致程序中断的一种指令流,异常一旦出现并且没有进行合理处理的话,那么程序就会中断执行. An exception is a flow of instruction that causes a program to interrupt in a propram. If an exception occurs and is not properly handled, the program is interrupted. (1)不产生异常的程序:

“全栈2019”Java异常第二十章:自定义异常详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异常第二十章:自定义异常详解 下一章 "全栈2019"Java异常第二十一章:finally不被执行的情况 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学

Java并发编程之---Lock框架详解

Java 并发开发:Lock 框架详解 摘要: 我们已经知道,synchronized 是Java的关键字,是Java的内置特性,在JVM层面实现了对临界资源的同步互斥访问,但 synchronized 粒度有些大,在处理实际问题时存在诸多局限性,比如响应中断等.Lock 提供了比 synchronized更广泛的锁操作,它能以更优雅的方式处理线程同步问题.本文以synchronized与Lock的对比为切入点,对Java中的Lock框架的枝干部分进行了详细介绍,最后给出了锁的一些相关概念. 一

java的集合框架最全详解

java的集合框架最全详解(图) 前言:数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作的方法. 在Java语言中,Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类).所有抽象出来的数据结构和操作(算法)统称为Java集合框架(JavaCollectionFramework). Java程序员在具体应用时,不必考虑数据结构和算法实现细节,只需要用这

Java的集合框架最全详解(图)

纯个人整理,如有错误请指正. java的集合框架最全详解(图) 前言:数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作的方法. 在Java语言中,Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类).所有抽象出来的数据结构和操作(算法)统称为Java集合框架(JavaCollectionFramework). Java程序员在具体应用时,不必考虑数据

Java魔法堂:String.format详解

Java魔法堂:String.format详解   目录     一.前言    二.重载方法     三.占位符     四.对字符.字符串进行格式化     五.对整数进行格式化     六.对浮点数进行格式化     七.对日期时间进行格式化     八.其他转换符  九.总结   参考 一.前言 String.format 作为文本处理工具,为我们提供强大而丰富的字符串格式化功能,为了不止步于简单调用 String.format("Hello %s", "John&q

Java魔法堂:String.format详解 (转载)

Java魔法堂:String.format详解   目录 一.前言 二.重载方法 三.占位符 四.对字符.字符串进行格式化 五.对整数进行格式化 六.对浮点数进行格式化 七.对日期时间进行格式化 八.其他转换符   九.总结   参考 一.前言 String.format 作为文本处理工具,为我们提供强大而丰富的字符串格式化功能,为了不止步于简单调用 String.format("Hello %s", "John"); ,下面将笔记整理并记录下来. 二.重载方法 /

JAVA通过JDBC连接Oracle数据库详解【转载】

JAVA通过JDBC连接Oracle数据库详解 (2011-03-15 00:10:03) 转载▼http://blog.sina.com.cn/s/blog_61da86dd0100q27w.html Java连接Oracle步骤: 1.注册加载驱动 驱动名:DRIVER="oracle.jdbc.driver.OracleDriver"; Class.forName("驱动类名"); 2.获得连接 数据库地址: URL="jdbc:oracle:thi

【转】Java魔法堂:String.format详解

Java魔法堂:String.format详解   目录     一.前言    二.重载方法     三.占位符     四.对字符.字符串进行格式化     五.对整数进行格式化     六.对浮点数进行格式化     七.对日期时间进行格式化     八.其他转换符  九.总结   参考 一.前言 String.format 作为文本处理工具,为我们提供强大而丰富的字符串格式化功能,为了不止步于简单调用 String.format("Hello %s", "John&q