当前位置:

首页 > 编程开发 > Java关键字throw、throws、Throwable怎么用

Java关键字throw、throws、Throwable怎么用

throw,意为“投掷、抛、扔”。Throw、Throws和Throwable三者都用于异常处理。1.ThrowableThrowable在Java中是异常处理这个分支的顶级父类,其它所有异常处理的实现都依赖于Throwable打开Java官方文档(Java8版本),找到Throwable,它的直接子类为Error和Exception。Error和Exception两者的特点在于Error异常程序无法处理,只能交由人工介入修改代码,比如栈溢出、堆溢出等等;而Exception异常可以提前发觉,并作出有效处

本文目录

      throw,意为“投掷、抛、扔”。Throw、Throws和Throwable三者都用于异常处理。

      1. Throwable

      Throwable在Java中是异常处理这个分支的顶级父类,其它所有异常处理的实现都依赖于Throwable

      打开Java官方文档(Java8版本),找到Throwable,它的直接子类为Error和Exception。

      Java关键字throw、throws、Throwable怎么用

      Error和Exception两者的特点在于Error异常程序无法处理,只能交由人工介入修改代码,比如栈溢出、堆溢出等等;而Exception异常可以提前发觉,并作出有效处理。

      1.1 扩展-Error

      在Error中,常见的有栈溢出和堆溢出等等。

      Java关键字throw、throws、Throwable怎么用

      举个例子,StackOverflowError

      public class ErrorTest {
          public static void main(String[] args) {
              main(args);
          }
      }

      无限递归,执行这个程序就会报栈溢出异常。

      Java关键字throw、throws、Throwable怎么用

      再比如堆异常,OutOfMemoryError

      public class ErrorTest {
          public static void main(String[] args) {
              Integer[] testArray = new Integer[1024*1024*1024];
          }
      }

      Java关键字throw、throws、Throwable怎么用

      1.2 扩展-Exception

      在Exception中就有非常多我们所熟知的异常情况了,比如NullPointerException(空指针异常)、ArrayIndexOutOfBoundsException(数组下标越界)、NumberFormatException(数字格式化异常)等等。

      public class ExceptionTest {
          public static void main(String[] args) {
              int[] testArray = null;
              System.out.println(testArray[0]);  //空指针异常
          }
      }
      public class ExceptionTest {
          public static void main(String[] args) {
              int[] testArray = new int[3];
              System.out.println(testArray[3]);   //数组下标越界
          }
      }
      public class ExceptionTest {
          public static void main(String[] args) {
              String num = "abc";
              System.out.println(Integer.parseInt(num));    //数字格式化异常
          }
      }

      2. throws

      throws应用在方法声明处,指明此方法在执行时可能会出现的异常类型。一旦该方法执行时出现异常,就会在异常代码处生成一个异常类的对象,此对象满足Throws后的异常类型时,就会被抛出。这里有两个过程,代码有异常时

      1. 生成一个异常对象;

      2. throws捕获到这个异常,将异常对象抛出

      throws和try-catch-finally一起称为异常处理的两种方式。

      try-catch-finally是在出现异常时主动处理掉异常,使得程序可以继续执行下去;而throws捕获到异常之后向上抛出异常对象,不去真正地处理这个异常。

      所谓向上抛出异常对象,是将异常对象交给调用者去处理,比如方法A调用方法B,B通过throws抛出异常,而A可以选择使用try-catch-finally处理掉异常,也可以通过throws继续向上抛出异常对象,直到异常被真正处理掉。如果一直没有方法去处理异常,异常对象最终会被抛给JVM,从而导致程序停止运行。

      @Test
      public void throwsTest(){   //调用者解决抛出的异常
          try{
              formatChange("abc");
          }
          catch (NumberFormatException e){
              System.out.println("转换格式错误!");
          }
          catch (Exception e){
              System.out.println("出现错误");
          }
      }
      private int formatChange(String str) throws NumberFormatException{    //出现异常向上抛出
          return Integer.parseInt(str);
      }

      2.1 扩展

      ——如何选择try-catch-finally还是throws?

      当一个方法中存在异常需要处理,在大多数情况下,既可以选择try-catch-finally直接处理掉这个异常,也可以选择throws向上抛出异常,交给调用者去处理(异常抛到最后,总要有一方真正地去处理这个异常,怎么处理?还是用try-catch-finally呗),在选择上比较自由,但是,出现以下两种情况时,需要遵循一定的规则(如有补充,敬请指出)。

      • 如果父类中被重写的方法没有使用throws抛出异常,则子类重写的方法也不能使用throws抛出异常,也就意味着这种情况必须使用try-catch-finally去处理。

      • 在方法A中,先后调用了另外的几种方法,这几种方法是递进关系执行的且其中很多方法都存在异常需要处理,这种情况建议被调用的几个方法使用throws向上抛出异常,在方法A中,使用try-catch-finally统一处理掉这些异常。

      针对第一条,这是一个规定,子类中重写的方法使用throws抛出的异常必须不大于父类中被重写的方法抛出异常的范围。举个例子,父类中的方法B抛出NullPointerException异常,则子类中重写B方法就不能抛出如Exception这种比NullPointerException范围更大的异常;如果父类中被重写的方法没有抛出任何异常,则子类更不能抛出异常。

      为什么?展示一段代码。

      //假设父类中的方法B抛出NullPointerException异常,子类中的方法B可以抛出Exception
      private void test(ParentClassTest parent){
          try{
              parent.B();
          }
          catch(NullPointerException e){
              System.out.println("出现了空指针异常");
          }
      }

      在本示例中,假设父类中的方法B抛出NullPointerException异常,子类中重写的方法B可以抛出Exception。那么传进给test方法的参数如果是父类的实例化对象,那么调用test方法没有任何问题。如果传进的参数是子类的实例化对象,再去调用子类重写的方法B,那么就有可能抛出Exception异常,try-catch结构就压不住这个异常了,这显然是一个不合理的操作。

      针对第二条,假设方法A中调用了方法C、D、E,这三个方法都有可能产生异常,且存在递进关系,也就是D、E执行需要C执行完成、E执行依赖C、D执行完成。那么就推荐在C、D、E中向上抛出异常,在方法A中集中处理。为什么?如果C、D、E都是向上抛出异常,而A使用try-catch-finally去处理这个异常,如果某个方法真的出现异常,则不再继续执行。而如果C、D、E都使用try-catch-finally直接解决掉异常,那么即使产生了异常,方法A也不会接收到异常的产生,那么还会接着往下执行,但是C出现了异常,再执行D、E没有任何意义。

      3. throw

      如果在程序编写时有手动抛出异常的需求,则可以使用throw

      throw使用在方法体内。与try-catch-finally和throws都不同,异常处理的两个阶段:1.遇到异常,生成异常对象;2.捕获到异常,进行抛出或处理。try-catch-finally和throws都处在第二个阶段,都是捕获到异常后的相关处理,一般使用系统根据异常类型自动生成的异常对象进行处理。而throw应用在第一阶段,手动地产生一个异常对象。

      举一个例子,判断一个数值是否为非负数,如果为负数,则抛出异常。

      class ThrowTest{
          private int Number;
          public void judge(int num){
              if(num>=0){
                  this.Number = num;
              }
              else{
                  throw new RuntimeException("传入参数为负数");
              }
          }
      }
      @Test
      public void test2(){
          ThrowTest throwTest = new ThrowTest();
          throwTest.judge(-100);
      }

      成功抛出异常。

      Java关键字throw、throws、Throwable怎么用

      使用try-catch捕获一下异常。

      @Test
      public void test2(){
          ThrowTest throwTest = new ThrowTest();
          try{
              throwTest.judge(-100);
          }
          catch (RuntimeException e){
              System.out.println(e.getMessage());
          }
      }

      Java关键字throw、throws、Throwable怎么用

      如果把throw抛出的异常改为Exception,则直接报错,也就是不能编译。Exception包含两种异常:编译时异常和运行时异常,前者在编译前就要检查是否有可能产生编译时异常;后者是在编译后运行时才会判断的异常。而throw new Exception包含了编译时异常,需要显式处理掉这个异常,怎么处理?try-catch-finally或者throws

      Java关键字throw、throws、Throwable怎么用

      class ThrowTest{
          private int Number;
          public void judge(int num) throws Exception{
              if(num>=0){
                  this.Number = num;
              }
              else{
                  throw new Exception("传入参数为负数");
              }
          }
      }

      调用方也要随着进行更改。

      @Test
      public void test2(){
          ThrowTest throwTest = new ThrowTest();
          try{
              throwTest.judge(-100);
          }
          catch (RuntimeException e){
              System.out.println(e.getMessage());
          }
          catch (Exception e){
              System.out.println(e.getMessage());
          }
      }

      Java关键字throw、throws、Throwable怎么用

      3.1 扩展

      ——自定义异常类

      throw还可以抛出自定义异常类。

      自定义异常类的声明需要继承于现有的异常体系。

      class MyException extends RuntimeException{
          static final long serialVersionUID = -703489719076939L;   //可以认为是一种标识
          public MyException(){}
          public MyException(String message){
              super(message);
          }
      }

      此时我们可以抛出自定义的异常

      class ThrowTest{
          private int Number;
          public void judge(int num) throws MyException{
              if(num>=0){
                  this.Number = num;
              }
              else{
                  throw new MyException("不能输入负数");
              }
          }
      }

      调用者修改

      @Test
      public void test2(){
          ThrowTest throwTest = new ThrowTest();
          try{
              throwTest.judge(-100);
          }
          catch (MyException e){
              System.out.println(e.getMessage());
          }
      }

      Java关键字throw、throws、Throwable怎么用

      本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
      作者最新文章
      编程开发 Java
      相关文章 更多
      Java单元测试入门:使用JUnit 5编写第一个测试用例
      Java单元测试入门:使用JUnit 5编写第一个测试用例

      面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

      Java变量未初始化报错解析:局部变量与成员变量默认值差异
      Java变量未初始化报错解析:局部变量与成员变量默认值差异

      深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

      Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
      Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

      详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

      Java中final与static final常量的定义及初始化规则
      Java中final与static final常量的定义及初始化规则

      深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

      Java抽象方法与接口方法的区别及选型建议
      Java抽象方法与接口方法的区别及选型建议

      深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

      Java实现HTTP请求与JSON解析的完整代码示例
      Java实现HTTP请求与JSON解析的完整代码示例

      本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

      Java递归出现StackOverflowError的原因分析及栈空间优化方案
      Java递归出现StackOverflowError的原因分析及栈空间优化方案

      详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

      Java空指针异常(NPE)的代码排查与修复实例
      Java空指针异常(NPE)的代码排查与修复实例

      针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

      selenium上传文件教程本地文件路径设置方法
      selenium上传文件教程本地文件路径设置方法

      深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

      大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
      大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

      针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

      查看更多
      精品专题 更多
      装机必备
      装机必备

      正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

      Windows
      Windows

      正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

      PDF教程
      PDF教程

      正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

      Mac软件 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      Aperty macOS版
      Aperty macOS版
      macOS

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      WINDOWS 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      PixTV 网页版
      PixTV 网页版
      Windows

      PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。