Java 中的异常处理除了捕获异常和处理异常之外,还包括声明异常和拋出异常。

实现声明和抛出异常的关键字非常相似,它们是 throws 和 throw

可以通过 throws 关键字在方法上声明该方法要拋出的异常,然后在方法内部通过 throw 拋出异常对象。

本节详细介绍在 Java 中如何声明异常和拋出异常。

throws 声明异常

当一个方法产生一个它不处理的异常时,那么就需要在该方法的头部声明这个异常,以便将该异常传递到方法的外部进行处理。使用 throws 声明的方法表示此方法不处理异常。throws 具体格式如下:

returnType method_name(paramList) throws Exception 1,Exception2,…{…}

其中,returnType 表示返回值类型;method_name 表示方法名;paramList 表示参数列表;Exception 1,Exception2,… 表示异常类。

如果有多个异常类,它们之间用逗号分隔。这些异常类可以是方法中调用了可能拋出异常的方法而产生的异常,也可以是方法体中生成并拋出的异常。

使用 throws 声明抛出异常的思路是,当前方法不知道如何处理这种类型的异常,该异常应该由向上一级的调用者处理;如果 main 方法也不知道如何处理这种类型的异常,也可以使用 throws 声明抛出异常,该异常将交给 JVM 处理。JVM 对异常的处理方法是,打印异常的跟踪栈信息,并中止程序运行,这就是前面程序在遇到异常后自动结束的原因。

例 1
创建一个 readFile() 方法,该方法用于读取文件内容,在读取的过程中可能会产生 IOException 异常,但是在该方法中不做任何的处理,而将可能发生的异常交给调用者处理。在 main() 方法中使用 try catch 捕获异常,并输出异常信息。代码如下:

import java.io.FileInputStream;
import java.io.IOException;public class  Test{public void readFile()throws IOException{//定义方法时声明异常FileInputStream file=new FileInputStream("test.txt");int f;while((f=file.read())!=-1){System.out.println((char)f);f=file.read();}file.close();}public static void main(String[] args)  {Test t=new Test();try{t.readFile();//调用readFile方法}catch(Exception e){System.out.println(e);//捕获异常}}
}

以上代码,首先在定义 readFile() 方法时用 throws 关键字声明在该方法中可能产生的异常,然后在 main() 方法中调用 readFile() 方法,并使用 catch 语句捕获产生的异常。

方法重写时声明抛出异常的限制
使用 throws 声明抛出异常时有一个限制,是方法重写中的一条规则:子类方法声明抛出的异常类型应该是父类方法声明抛出的异常类型的子类或相同,子类方法声明抛出的异常不允许比父类方法声明抛出的异常多。看如下程序。
使用 throws 声明抛出异常时有一个限制,是方法重写中的一条规则:子类方法声明抛出的异常类型应该是父类方法声明抛出的异常类型的子类或相同,子类方法声明抛出的异常不允许比父类方法声明抛出的异常多。看如下程序。

public class OverrideThrows {public void test() throws IOException {FileInputStream fis = new FileInputStream("a.txt");}
}
class Sub extends OverrideThrows {// 子类方法声明抛出了比父类方法更大的异常// 所以下面方法出错public void test() throws Exception {}
}

上面程序中 Sub 子类中的 test() 方法声明抛出 Exception,该 Exception 是其父类声明抛出异常 IOException 类的父类,这将导致程序无法通过编译。

所以在编写类继承代码时要注意,子类在重写父类带 throws 子句的方法时,子类方法声明中的 throws 子句不能出现父类对应方法的 throws 子句中没有的异常类型,因此 throws 子句可以限制子类的行为。也就是说,子类方法拋出的异常不能超过父类定义的范围。

throw 拋出异常

与 throws 不同的是,throw 语句用来直接拋出一个异常,后接一个可拋出的异常类对象,其语法格式如下:

throw ExceptionObject;

其中,ExceptionObject 必须是 Throwable 类或其子类的对象。如果是自定义异常类,也必须是 Throwable 的直接或间接子类。例如,以下语句在编译时将会产生语法错误:

throw new String("拋出异常");    // String类不是Throwable类的子类

当 throw 语句执行时,它后面的语句将不执行,此时程序转向调用者程序,寻找与之相匹配的 catch 语句,执行相应的异常处理程序。如果没有找到相匹配的 catch 语句,则再转向上一层的调用程序。这样逐层向上,直到最外层的异常处理程序终止程序并打印出调用栈情况。

throw 关键字不会单独使用,它的使用完全符合异常的处理机制,但是,一般来讲用户都在避免异常的产生,所以不会手工抛出一个新的异常类的实例,而往往会抛出程序中已经产生的异常类的实例。

例 2
在某仓库管理系统中,要求管理员的用户名需要由 8 位以上的字母或者数字组成,不能含有其他的字符。当长度在 8 位以下时拋出异常,并显示异常信息;当字符含有非字母或者数字时,同样拋出异常,显示异常信息。代码如下:

import java.util.Scanner;
public class Test {public boolean validateUserName(String username) {boolean con = false;if (username.length() > 8) {// 判断用户名长度是否大于8位for (int i = 0; i < username.length(); i++) {char ch = username.charAt(i); // 获取每一位字符if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {con = true;} else {con = false;throw new IllegalArgumentException("用户名只能由字母和数字组成!");}}} else {throw new IllegalArgumentException("用户名长度必须大于 8 位!");}return con;}public static void main(String[] args) {Test05 te = new Test05();Scanner input = new Scanner(System.in);System.out.println("请输入用户名:");String username = input.next();try {boolean con = te.validateUserName(username);if (con) {System.out.println("用户名输入正确!");}} catch (IllegalArgumentException e) {System.out.println(e);}}
}

如上述代码,在 validateUserName() 方法中两处拋出了 IllegalArgumentException 异常,即当用户名字符含有非字母或者数字以及长度不够 8 位时。在 main() 方法中,调用了 validateUserName() 方法,并使用 catch 语句捕获该方法可能拋出的异常。

运行程序,当用户输入的用户名包含非字母或者数字的字符时,程序输出异常信息,如下所示。

请输入用户名:
ligulasizhaosi!!!!!!
java.lang.IllegalArgumentException: 用户名只能由字母和数字组成!

当用户输入的用户名长度不够 8 位时,程序同样会输出异常信息,如下所示。

请输入用户名:
admin
java.lang.IllegalArgumentException: 用户名长度必须大于 8 位!

throws 关键字和 throw 关键字在使用上的几点区别如下:

  • throws 用来声明一个方法可能抛出的所有异常信息,表示出现异常的一种可能性,但并不一定会发生这些异常;throw
    则是指拋出的一个具体的异常类型,执行 throw 则一定抛出了某种异常对象。
  • 通常在一个方法(类)的声明处通过 throws 声明方法(类)可能拋出的异常信息,而在方法(类)内部通过 throw
    声明一个具体的异常信息。
  • throws 通常不用显示地捕获异常,可由系统自动将所有捕获的异常信息抛给上级方法; throw
    则需要用户自己捕获相关的异常,而后再对其进行相关包装,最后将包装后的异常信息抛出。

1.10 throws和throw:声明和抛出异常相关推荐

  1. Java中throws和throw的区别讲解

    当然,你需要明白异常在Java中式以一个对象来看待. 并且所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,但是一般情况下Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示 ...

  2. java中的抛出异常throws与throw

    throws与throw throws是方法可能抛出异常的声明.(用在声明方法时,表示该方法可能要抛出异常) 语法:[(修饰符)](返回值类型)(方法名)([参数列表])[throws(异常类)]{. ...

  3. 什么是异常?为什么要抛出异常?throws和throw的区别

    文章目录 前言 1. 异常是什么? 1.1 概述:异常就是程序出现了不正常的情况 1.2 体系结构 1.3 编译时异常和运行时异常的区别 1.4 Throwable成员方法:返回异常信息方法 2. 怎 ...

  4. throws和throw抛出异常的使用规则

    一直对java中的throws和throw不太理解.最近一直在查这两个方面的资料,算是能明白一点吧.如果我下面的观点哪有不对,希望指出来,我加以改进.         throw:(针对对象的做法) ...

  5. java 异常处理的关键字_java异常,异常处理,异常类 关键字:throws 和 throw 自定义的异常类...

    packagecn.kecheng;importjava.util.Scanner;/**异常:异常是指在程序的运行过程中所发生的不正常的情况,它会中断正在运行的程序 异常处理机制:java中通过异常 ...

  6. 22.Java之异常处理(异常介绍,异常体系图一览,运行时异常,编译异常,try-catch方式处理异常,throws异常处理,自定义异常,throws 和 throw 的区别)

    22.1.异常介绍 Java语言中,将程序执行中发生的不正常情况称为 "异常" (开发过程中的语法错误和逻辑错误不是异常) 执行过程中所发生的异常事件分为两大类: Error:Ja ...

  7. Java throws和throw

    throws 声明异常 当一个方法产生一个它不处理的异常时,那么就需要在该方法的头部声明这个异常,以便将该异常传递到方法的外部进行处理.使用 throws 声明的方法表示此方法不处理异常.throws ...

  8. throws和throw的作用

    throws和throw的作用 1.throws 2. throw 3. RuntimeException 4.总结(非常重要) 1.throws throws用来修饰一个方法,表示该方法如果产生异常 ...

  9. -1-6 java 异常简单介绍 java异常 异常体系 Throwable 分类 throws和throw 异常处理 自定义异常...

    异常 异常:异常就是Java程序在运行过程中出现的错误. 异常由来:问题也是现实生活中一个具体事务,也可以通过java 的类的形式进行描述,并封装成对象. 其实就是Java对不正常情况进行描述后的对象 ...

最新文章

  1. 【科普】为什么985大学在大一上C语言课??
  2. lucky前面加a还是an_微信昵称前加个“A” 不是微商就是销售?看看这个“A”的含义!...
  3. char类型和Unicode编码
  4. 在存储过程中构建动态SQL
  5. [转]Spring注解-@Configuration注解、@Bean注解以及配置自动扫描、bean作用域
  6. [CF1107E]Vasya and Binary String【区间DP】
  7. daysmatter安卓版_days matter
  8. 如何使用以下命令 ls cat mv touch 以及如何使用 explainshell.com 这个网站
  9. Linux 命令(37)—— free 命令
  10. C++动态类型与静态类型
  11. 重构-使代码更简洁优美:实际经验之谈(提供一技巧,让你省掉N多代码)
  12. 我怕三十的红包太多,先发为敬!
  13. App丛林法则:如何抓住“女人心”
  14. 基于吸盘的scara机械臂
  15. python之selenium设置浏览器为手机模式(开发者模式)
  16. Android 框架MVP
  17. facebook审核流程
  18. NHWC BGR -> NCHW RGB
  19. 地下管线监控系统中互联网WebGL三维可视化构建技术 ThingJS
  20. 我们到底该不该去初创公司上班?

热门文章

  1. 成功解决Scrapy框架的问题ModuleNotFoundError: No module named 'win32api'
  2. 成功解决OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cv::cvtColor
  3. Linux系统管理01
  4. linux下的/dev/shm/ 以及与swap目录的区别【转】
  5. 使用ML.NET + Azure DevOps + Azure Container Instances打造机器学习生产化
  6. 《精通Python设计模式》学习结构型之享元模式
  7. C++ 管理数据内存的方法
  8. 拓扑排序之变量序列代码
  9. 文件与目录权限,文件查找
  10. linux 上传带宽限速