简述Java中throw-throws异常抛出


Posted in Java/Android onAugust 07, 2021

      任何Java代码都可以抛出异常,如:自己编写的代码、来自Java开发环境包中代码,或者Java运行时系统。无论是谁,都可以通过Java的throw语句抛出异常。从方法中抛出的任何异常都必须使用throws子句。

一、throws抛出异常

      如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常。例如汽车在运行时可能会出现故障,汽车本身没办法处理这个故障,那就让开车的人来处理。

      throws语句用在方法定义时声明该方法要抛出的异常类型,如果抛出的是Exception异常类型,则该方法被声明为抛出所有的异常。多个异常可使用逗号分割。throws语句的语法格式为:

methodname throws Exception1,Exception2,..,ExceptionN{  }

      方法名后的throws Exception1,Exception2,…,ExceptionN 为声明要抛出的异常列表。当方法抛出异常列表的异常时,方法将不对这些类型及其子类类型的异常作处理,而抛向调用该方法的方法,由他去处理。

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

Throws抛出异常的规则:

  1. 如果是不可查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。
  2. 如果一个方法可能出现可查异常(checked exception),要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误。
  3. 只有当抛出了异常时,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出。
  4. 调用方法必须遵循任何可查异常的处理和声明规则。若覆盖一个方法,则不能声明与覆盖方法不同的异常。声明的任何异常必须是被覆盖方法所声明异常的同类或子类。

二、使用throw抛出异常

      throw总是出现在方法体中,用来抛出一个Throwable类型的异常。程序会在throw语句后立即终止,它后面的语句执行不到,然后在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块。

      我们知道,异常是异常类的实例对象,我们可以创建异常类的实例对象通过throw语句抛出。该语句的语法格式为:

throw new exceptionname;

      例如抛出一个IOException类的异常对象:

throw new IOException;

       要注意的是,throw 抛出的只能够是可抛出类Throwable 或者其子类的实例对象。下面的操作是错误的,因为String 不是Throwable 类的子类。

throw new String("exception");

      如果抛出了可查异常,则还应该在方法头部声明方法可能抛出的异常类型。该方法的调用者也必须检查处理抛出的异常。

      如果所有方法都层层上抛获取的异常,最终JVM会进行处理,处理也很简单,就是打印异常消息和堆栈信息。如果抛出的是Error或RuntimeException,则该方法的调用者可选择处理该异常。

throw的示例:

public class TestException {  
    public static void main(String[] args) {  
        int a = 6;  
        int b = 0;  
        
        try { 
            if (b == 0) {
    throw new ArithmeticException(); 
    //"除数为0"等ArithmeticException,是RuntimException的子类。而运行时异常将由运行时系统自动抛出,不需要使用throw语句,这里把throw new ArithmeticException()去掉也是不影响运行结果的。
   }
            System.out.println("a/b的值是:" + a / b);  
        } catch (ArithmeticException e) {
            System.out.println("程序出现异常,变量b不能为0。");  
        }  
        
        System.out.println("程序正常结束。");  
    }  
}

输出结果为:

程序出现异常,变量b不能为0。
程序正常结束。

三、比较

3.1 在声明方法时候抛出异常 

为什么要在声明方法抛出异常?
答:方法是否抛出异常与方法返回值的类型一样重要。假设方法抛出异常却没有声明该方法将抛出异常,那么客户程序员可以调用这个方法而且不用编写处理异常的代码。那么,一旦出现异常,那么这个异常就没有合适的异常控制器来解决。

为什么抛出的异常一定是可检查异常(除了Exception中的RuntimeException及其子类以外,其他的Exception类及其子类)?
答:RuntimeException与Error可以在任何代码中产生,它们不需要由程序员显示的抛出,一旦出现错误,那么相应的异常会被自动抛出。遇到Error,程序员一般是无能为力的;遇到RuntimeException,那么一定是程序存在逻辑错误,要对程序进行修改;只有可检查异常才是程序员所关心的,程序应该且仅应该抛出或处理可检查异常。而可检查异常是由程序员抛出的,这分为两种情况:客户程序员调用会抛出异常的库函数;客户程序员自己使用throw语句抛出异常。

注意: 覆盖父类某方法的子类方法不能抛出比父类方法更多的异常,所以,有时设计父类的方法时会声明抛出异常,但实际的实现方法的代码却并不抛出异常,这样做的目的就是为了方便子类方法覆盖父类方法时可以抛出异常。

3.2 在方法中抛出异常

抛出什么异常?
答:对于一个异常对象,真正有用的信息是异常的对象类型,而异常对象本身毫无意义。比如一个异常对象的类型是ClassCastException,那么这个类名就是唯一有用的信息。所以,在选择抛出什么异常时,最关键的就是选择异常的类名能够明确说明异常情况的类。

异常对象通常有两种构造函数:一种是无参数的构造函数;另一种是带一个字符串的构造函数,这个字符串将作为这个异常对象除了类型名以外的额外说明。

使用finally块释放资源
finally关键字保证无论程序使用任何方式离开try块,finally中的语句都会被执行。因此,当你需要一个地方来执行在任何情况下都必须执行的代码时,就可以将这些代码放入finally块中。当你的程序中使用了外界资源,如数据库连接,文件等,必须将释放这些资源的代码写入finally块中。

注意: 在finally块中不能抛出异常。JAVA异常处理机制保证无论在任何情况下必须先执行finally块然后再离开try块,因此在try块中发生异常的时候,JAVA虚拟机先转到finally块执行finally块中的代码,finally块执行完毕后,再向外抛出异常。如果在finally块中抛出异常,try块捕捉的异常就不能抛出,外部捕捉到的异常就是finally块中的异常信息,而try块中发生的真正的异常堆栈信息则丢失了。

到此这篇关于简述Java中throw-throws异常抛出的文章就介绍到这了,更多相关Java throw-throws异常抛出内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Java/Android 相关文章推荐
Springboot如何使用logback实现多环境配置?
Jun 16 Java/Android
ConstraintValidator类如何实现自定义注解校验前端传参
Jun 18 Java/Android
Java Optional<Foo>转换成List<Bar>的实例方法
Jun 20 Java/Android
浅谈什么是SpringBoot异常处理自动配置的原理
Jun 21 Java/Android
基于Java的MathML转图片的方法(示例代码)
Jun 23 Java/Android
Java设计模式之代理模式
Apr 22 Java/Android
带你了解Java中的ForkJoin
Apr 28 Java/Android
Java设计模式中的命令模式
Apr 28 Java/Android
Java实现超大Excel文件解析(XSSF,SXSSF,easyExcel)
Jul 15 Java/Android
volatile保证可见性及重排序方法
Aug 05 Java/Android
Java代码规范与质量检测插件SonarLint的使用
Aug 05 Java/Android
Java比较两个对象中全部属性值是否相等的方法
Aug 07 #Java/Android
Java org.w3c.dom.Document 类方法引用报错
Aug 07 #Java/Android
springboot+WebMagic+MyBatis爬虫框架的使用
Aug 07 #Java/Android
mybatis中注解与xml配置的对应关系和对比分析
Aug 04 #Java/Android
浅谈sql_@SelectProvider及使用注意说明
Aug 04 #Java/Android
mybatis3中@SelectProvider传递参数方式
Aug 04 #Java/Android
浅谈Java父子类加载顺序
Aug 04 #Java/Android
You might like
PHP5.2中date()函数显示时间与北京时间相差8小时的解决办法
2009/05/28 PHP
destoon实现商铺管理主页设置增加新菜单的方法
2014/06/26 PHP
thinkphp区间查询、统计查询与SQL直接查询实例分析
2014/11/24 PHP
9条PHP编程小知识及易犯的小错误
2015/01/22 PHP
Thinkphp5框架实现获取数据库数据到视图的方法
2019/08/14 PHP
懒就要懒到底——鼠标自动点击(含时间判断)
2007/02/20 Javascript
利用js对象弹出一个层
2008/03/26 Javascript
Javascript 键盘事件的组合使用实现代码
2012/05/04 Javascript
浅析LigerUi开发中谨慎载入common.css文件
2013/07/09 Javascript
BootStrap智能表单实战系列(六)表单编辑页面的数据绑定
2016/06/13 Javascript
Angular.js 实现数字转换汉字实例代码
2016/07/14 Javascript
javascript this详细介绍
2016/09/19 Javascript
jQuery实现的简单手风琴效果示例
2018/08/29 jQuery
JS脚本实现定时到网站上签到/签退功能
2020/04/22 Javascript
微信小程序文章详情功能完整实例
2020/06/03 Javascript
[01:00:52]2018DOTA2亚洲邀请赛 4.4 淘汰赛 EG vs LGD 第一场
2018/04/05 DOTA
python算法学习之基数排序实例
2013/12/18 Python
Python中使用pprint函数进行格式化输出的教程
2015/04/07 Python
Python3多线程操作简单示例
2018/05/22 Python
10个Python小技巧你值得拥有
2018/09/29 Python
Python对象转换为json的方法步骤
2019/04/25 Python
Python Sphinx使用实例及问题解决
2020/01/17 Python
Centos7下源码安装Python3 及shell 脚本自动安装Python3的教程
2020/03/07 Python
完美解决pyinstaller打包报错找不到依赖pypiwin32或pywin32-ctypes的错误
2020/04/01 Python
Python configparser模块应用过程解析
2020/08/14 Python
无需JS和jQuery代码实现CSS3鼠标浮动放大图片
2016/11/21 HTML / CSS
世界上最大的皮肤科医生拥有和经营的美容网站:LovelySkin
2021/01/03 全球购物
C语言编程题
2015/03/09 面试题
中间件的定义
2016/08/09 面试题
酒店员工培训方案
2014/06/02 职场文书
2014年商场国庆节活动策划方案
2014/09/16 职场文书
关于运动会广播稿300字
2014/10/05 职场文书
教师工作能力自我评价
2015/03/04 职场文书
2015年统计员个人工作总结
2015/07/23 职场文书
Python中threading库实现线程锁与释放锁
2021/05/17 Python
Python+腾讯云服务器实现每日自动健康打卡
2021/12/06 Python