解析Java中未被捕获的异常以及try语句的嵌套使用_java

Java未被捕获的异常
在你学习在程序中处理异常之前,看一看如果你不处理它们会有什么情况发生是很有好处的。下面的小程序包括一个故意导致被零除错误的表达式。

class Exc0 {
  public static void main(String args[]) {
    int d = 0;
    int a = 42 / d;
  }
}

当Java运行时系统检查到被零除的情况,它构造一个新的异常对象然后抛出该异常。这导致Exc0的执行停止,因为一旦一个异常被抛出,它必须被一个异常处理程序捕获并且被立即处理。该例中,我们没有提供任何我们自己的异常处理程序,所以异常被Java运行时系统的默认处理程序捕获。任何不是被你程序捕获的异常最终都会被该默认处理程序处理。默认处理程序显示一个描述异常的字符串,打印异常发生处的堆栈轨迹并且终止程序。

下面是由标准javaJDK运行时解释器执行该程序所产生的输出:

  java.lang.ArithmeticException: / by zero
  at Exc0.main(Exc0.java:4)

注意,类名Exc0,方法名main,文件名Exc0.java和行数4是怎样被包括在一个简单的堆栈使用轨迹中的。还有,注意抛出的异常类型是Exception的一个名为ArithmeticException的子类,该子类更明确的描述了何种类型的错误方法。本章后面部分将讨论,Java提供多个内置的与可能产生的不同种类运行时错误相匹配的异常类型。

堆栈轨迹将显示导致错误产生的方法调用序列。例如,下面是前面程序的另一个版本,它介绍了相同的错误,但是错误是在main( )方法之外的另一个方法中产生的:

class Exc1 {
  static void subroutine() {
    int d = 0;
    int a = 10 / d;
  }
  public static void main(String args[]) {
    Exc1.subroutine();
  }
}

默认异常处理器的堆栈轨迹结果表明了整个调用栈是怎样显示的:

  java.lang.ArithmeticException: / by zero
  at Exc1.subroutine(Exc1.java:4)
  at Exc1.main(Exc1.java:7)

如你所见,栈底是main的第7行,该行调用了subroutine( )方法。该方法在第4行导致了异常。调用堆栈对于调试来说是很重要的,因为它查明了导致错误的精确的步骤。

Java try语句的嵌套
Try语句可以被嵌套。也就是说,一个try语句可以在另一个try块内部。每次进入try语句,异常的前后关系都会被推入堆栈。如果一个内部的try语句不含特殊异常的catch处理程序,堆栈将弹出,下一个try语句的catch处理程序将检查是否与之匹配。这个过程将继续直到一个catch语句匹配成功,或者是直到所有的嵌套try语句被检查耗尽。如果没有catch语句匹配,Java的运行时系统将处理这个异常。下面是运用嵌套try语句的一个例子:

// An example of nested try statements.
class NestTry {
  public static void main(String args[]) {
    try {
      int a = args.length;
      /* If no command-line args are present,the following statement will generate a divide-by-zero exception. */
      int b = 42 / a;
      System.out.println("a = " + a);
      try { // nested try block
        /* If one command-line arg is used,then a divide-by-zero exception will be generated by the following code. */
        if(a==1) a = a/(a-a); // division by zero
        /* If two command-line args are used,then generate an out-of-bounds exception. */
        if(a==2) {
          int c[] = { 1 };
          c[42] = 99; // generate an out-of-bounds exception
        }
      } catch(ArrayIndexOutOfBoundsException e) {
        System.out.println("Array index out-of-bounds: " + e);
      }
    } catch(ArithmeticException e) {
      System.out.println("Divide by 0: " + e);
    }
  }
}

如你所见,该程序在一个try块中嵌套了另一个try块。程序工作如下:当你在没有命令行参数的情况下执行该程序,外面的try块将产生一个被零除的异常。程序在有一个命令行参数条件下执行,由嵌套的try块产生一个被零除的错误。因为内部的块不匹配这个异常,它将把异常传给外部的try块,在那里异常被处理。如果你在具有两个命令行参数的条件下执行该程序,由内部try块产生一个数组边界异常。下面的结果阐述了每一种情况:

C:\>java NestTry
Divide by 0: java.lang.ArithmeticException: / by zero
C:\>java NestTry One
a = 1
Divide by 0: java.lang.ArithmeticException: / by zero
C:\>java NestTry One Two
a = 2
Array index out-of-bounds: java.lang.ArrayIndexOutOfBoundsException

当有方法调用时,try语句的嵌套可以很隐蔽的发生。例如,你可以把对方法的调用放在一个try块中。在该方法内部,有另一个try语句。这种情况下,方法内部的try仍然是嵌套在外部调用该方法的try块中的。下面是前面例子的修改,嵌套的try块移到了方法nesttry( )的内部:

/* Try statements can be implicitly nested via calls to methods. */
class MethNestTry {
  static void nesttry(int a) {
    try { // nested try block
      /* If one command-line arg is used,then a divide-by-zero exception will be generated by the following code. */
      if(a==1) a = a/(a-a); // division by zero
      /* If two command-line args are used,then generate an out-of-bounds exception. */
      if(a==2) {
        int c[] = { 1 };
        c[42] = 99; // generate an out-of-bounds exception
      }
    } catch(ArrayIndexOutOfBoundsException e) {
      System.out.println("Array index out-of-bounds: " + e);
    }
  }

  public static void main(String args[]) {
    try {
      int a = args.length;
      /* If no command-line args are present,the following statement will generate a divide-by-zero exception. */
      int b = 42 / a;
      System.out.println("a = " + a);
      nesttry(a);
    } catch(ArithmeticException e) {
      System.out.println("Divide by 0: " + e);
    }
  }
}

该程序的输出与前面的例子相同。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, 异常
try
try catch 捕获异常、正则捕获组不能嵌套、try catch 嵌套、try catch可以嵌套吗、java try catch 嵌套,以便于您获取更多的相关知识。

时间: 2024-08-17 14:24:47

解析Java中未被捕获的异常以及try语句的嵌套使用_java的相关文章

解析Java中的定时器及使用定时器制作弹弹球游戏的示例_java

  在我们编程过程中如果需要执行一些简单的定时任务,无须做复杂的控制,我们可以考虑使用JDK中的Timer定时任务来实现.下面LZ就其原理.实例以及Timer缺陷三个方面来解析java Timer定时器. 一.简介      在java中一个完整定时任务需要由Timer.TimerTask两个类来配合完成. API中是这样定义他们的,Timer:一种工具,线程用其安排以后在后台线程中执行的任务.可安排任务执行一次,或者定期重复执行.由TimerTask:Timer 安排为一次执行或重复执行的任务

websphere服务器中出现可捕获的异常时报错

问题描述 websphere服务器中出现可捕获的异常时报这个错,用的jsp中的error页面做的捕获异常提示,什么原因?错误信息:com.ibm.websphere.servlet.error.ServletErrorReport:java.lang.NoClassDefFoundError:org/eclipse/hyades/internal/logging/core/internationalization/InternationalizationUtilities详细信息:[15-2-2

java中double类型运算结果异常的解决方法_java

问题: 对两个double类型的值进行运算,有时会出现结果值异常的问题.比如: System.out.println(19.99+20); System.out.println(1.0-0.66); System.out.println(0.033*100); System.out.println(12.3/100); 输出: 39.989999999999995 0.33999999999999997 3.3000000000000003 0.12300000000000001 解决方法: J

解析Java中的String对象的数据类型

  解析Java中的String对象的数据类型     [摘要] 本文将全面解析Java中的String对象的数据类型.[关键字] Java 技巧   1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. new String()和new String("")都是申明一个新的空字符串,是空串不是null: 3. String str="

java中的常量为什么不能在try catch语句中赋值?

问题描述 java中的常量为什么不能在try catch语句中赋值? 成员位置声明一个常量,想在try catch 语句中赋值,会报错,不明白为什么会这样 解决方案 常量可以在try catch中赋值的,try这种就相当于一个语句块,只是提供了对异常的处理而已. 解决方案二: try-catch语句try-catch语句匿名类,try-catch语句 解决方案三: java中的常量声明时就需要初始化赋值.常量是始终不变的量,不能改变其常量值 解决方案四: 声明常量时就需要初始化赋值,不然会报错:

eval-怎么在java中实现类似show dbs 这样的mongo语句啊?

问题描述 怎么在java中实现类似show dbs 这样的mongo语句啊? 怎么在java中实现类似show dbs 这样的mongo语句啊?是用db.eval这个方法吗?具体怎么用啊,求指教啊 解决方案 mongo 语句

解析Java中所有错误和异常的父类java.lang.Throwable_java

在java语言中,错误类的基类是java.lang.Error,异常类的基类是java.lang.Exception. 1)相同点:java.lang.Error和java.lang.Exception都是java.lang.Throwable的子类,因此java.lang.Error和java.lang.Exception自身及其子类都可以作为throw的使用对象,如:throw new MyError();和throw new MyException();其中,MyError类是java.l

深入解析Java中的Class Loader类加载器_java

类加载的过程类加载器的主要工作就是把类文件加载到JVM中.如下图所示,其过程分为三步: 1.加载:定位要加载的类文件,并将其字节流装载到JVM中: 2.链接:给要加载的类分配最基本的内存结构保存其信息,比如属性,方法以及引用的类.在该阶段,该类还处于不可用状态: (1)验证:对加载的字节流进行验证,比如格式上的,安全方面的: (2)内存分配:为该类准备内存空间来表示其属性,方法以及引用的类: (3)解析:加载该类所引用的其它类,比如父类,实现的接口等. 3.初始化:对类变量进行赋值. 类加载器的

深入解析Java中的内部类_java

概述 最近学习python,发现python是支持多继承的,这让我想起Java是通过内部类实现的这套机制.这篇文章不是讲如何通过内部类实现多继承,而是总结一下内部类的类型和使用方法. Java内部类分为:     非静态内部类     静态内部类     局部内部类     匿名内部类 内部类在Android源码中被大量的使用,先介绍一下这四种内部类的共同点:     内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号.     内部类不