`

Java异常学习心得

    博客分类:
  • JSE
阅读更多

 

Java 异常学习心得
本文重在 Java 中异常机制的一些概念。写本文的目的在于方便我很长时间后若是忘了这些东西可以通过这片文章迅速回忆起来。
1.
异常机制
1.1
异常机制是指当程序出现错误后,程序如何处理。具体来说,异常机制提供了程序退出的安全通道。当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器。
1.2
传统的处理异常的办法是,函数返回一个特殊的结果来表示出现异常(通常这个特殊结果是大家约定俗称的),调用该函数的程序负责检查并分析函数返回的结果。这样做有如下的弊端:例如函数返回 -1 代表出现异常,但是如果函数确实要返回 -1 这个正确的值时就会出现混淆;可读性降低,将程序代码与处理异常的代码混爹在一起;由调用函数的程序来分析错误,这就要求客户程序员对库函数有很深的了解。
1.3
异常处理的流程
1.3.1
遇到错误,方法立即结束,并不返回一个值;同时,抛出一个异常对象
1.3.2
调用该方法的程序也不会继续执行下去,而是搜索一个可以处理该异常的异常处理器,并执行其中的代码

2
异常的分类
2.1
异常的分类
2.1.1
异常的继承结构:基类为 Throwable Error Exception 继承 Throwable RuntimeException IOException 等继承 Exception ,具体的 RuntimeException 继承 RuntimeException
2.1.2
Error
RuntimeException 及其子类成为未检查异常( unchecked ),其它异常成为已检查异常( checked )。
2.2
每个类型的异常的特点
2.2.1 Error
体系
Error
类体系描述了 Java 运行系统中的内部错误以及资源耗尽的情形。应用程序不应该抛出这种类型的对象(一般是由虚拟机抛出)。如果出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以,在进行程序设计时,应该更关注 Exception 体系。
2.2.2 Exception
体系
Exception
体系包括 RuntimeException 体系和其他非 RuntimeException 的体系
2.2.2.1 RuntimeException
RuntimeException
体系包括错误的类型转换、数组越界访问和试图访问空指针等等。处理 RuntimeException 的原则是:如果出现 RuntimeException ,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。
2.2.2.2
其他( IOException 等等)
这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。
2.3
C++ 异常分类的不同
2.3.1
其实, Java RuntimeException 这个类名起的并不恰当,因为任何异常都是运行时出现的。(在编译时出现的错误并不是异常,换句话说,异常就是为了解决程序运行时出现的的错误)。
2.3.2
C++
logic_error Java 中的 RuntimeException 是等价的,而 runtime_error Java 中非 RuntimeException 类型的异常是等价的。
3
异常的使用方法

3.1
声明方法抛出异常
3.1.1
语法: throws (略)
3.1.2
为什么要声明方法抛出异常?
方法是否抛出异常与方法返回值的类型一样重要。假设方法抛出异常确没有声明该方法将抛出异常,那么客户程序员可以调用这个方法而且不用编写处理异常的代码。那么,一旦出现异常,那么这个异常就没有合适的异常控制器来解决。
3.1.3
为什么抛出的异常一定是已检查异常?
RuntimeException
Error 可以在任何代码中产生,它们不需要由程序员显示的抛出,一旦出现错误,那么相应的异常会被自动抛出。而已检查异常是由程序员抛出的,这分为两种情况:客户程序员调用会抛出异常的库函数(库函数的异常由库程序员抛出);客户程序员自己使用 throw 语句抛出异常。遇到 Error ,程序员一般是无能为力的;遇到 RuntimeException ,那么一定是程序存在逻辑错误,要对程序进行修改(相当于调试的一种方法);只有已检查异常才是程序员所关心的,程序应该且仅应该抛出或处理已检查异常。
3.1.4
注意:覆盖父类某方法的子类方法不能抛出比父类方法更多的异常,所以,有时设计父类的方法时会声明抛出异常,但实际的实现方法的代码却并不抛出异常,这样做的目的就是为了方便子类方法覆盖父类方法时可以抛出异常。
3.2
如何抛出异常
3.2.1
语法: throw (略)
3.2.2
抛出什么异常?
对于一个异常对象,真正有用的信息时异常的对象类型,而异常对象本身毫无意义。比如一个异常对象的类型是 ClassCastException ,那么这个类名就是唯一有用的信息。所以,在选择抛出什么异常时,最关键的就是选择异常的类名能够明确说明异常情况的类。
3.2.3
异常对象通常有两种构造函数:一种是无参数的构造函数;另一种是带一个字符串的构造函数,这个字符串将作为这个异常对象除了类型名以外的额外说明。
3.2.4
创建自己的异常:当 Java 内置的异常都不能明确的说明异常情况的时候,需要创建自己的异常。需要注意的是,唯一有用的就是类型名这个信息,所以不要在异常类的设计上花费精力。
3.3
捕获异常
如果一个异常没有被处理,那么,对于一个非图形界面的程序而言,该程序会被中止并输出异常信息;对于一个图形界面程序,也会输出异常的信息,但是程序并不中止,而是返回用 Ы 缑娲 分小 ?BR> 3.3.1 语法: try catch finally (略)
控制器模块必须紧接在 try 块后面。若掷出一个异常,异常控制机制会搜寻参数与异常类型相符的第一个控制器随后它会进入那个 catch
从句,并认为异常已得到控制。一旦 catch 从句结束对控制器的搜索也会停止。
3.3.1.1
捕获多个异常(注意语法与捕获的顺序)(略)
3.3.1.2 finally
的用法与异常处理流程(略)
3.3.2
异常处理做什么?
对于 Java 来说,由于有了垃圾收集,所以异常处理并不需要回收内存。但是依然有一些资源需要程序员来收集,比如文件、网络连接和图片等资源。
3.3.3
应该声明方法抛出异常还是在方法中捕获异常?
原则:捕捉并处理哪些知道如何处理的异常,而传递哪些不知道如何处理的异常
3.3.4
再次抛出异常
3.3.4.1
为什么要再次抛出异常?
在本级中,只能处理一部分内容,有些处理需要在更高一级的环境中完成,所以应该再次抛出异常。这样可以使每级的异常处理器处理它能够处理的异常。
3.3.4.2
异常处理流程
对应与同一 try 块的 catch 块将被忽略,抛出的异常将进入更高的一级。
4
关于异常的其他问题
4.1
过度使用异常
首先,使用异常很方便,所以程序员一般不再愿意编写处理错误的代码,而仅仅是简简单单的抛出一个异常。这样做是不对的,对于完全已知的错误,应该编写处理这种错误的代码,增加程序的鲁棒性。另外,异常机制的效率很差。
4.2
将异常与普通错误区分开
对于普通的完全一致的错误,应该编写处理这种错误的代码,增加程序的鲁棒性。只有外部的不能确定和预知的运行时错误才需要使用异常。
4.3
异常对象中包含的信息
一般情况下,异常对象唯一有用的信息就是类型信息。但使用异常带字符串的构造函数时,这个字符串还可以作为额外的信息。调用异常对象的 getMessage() toString() 或者 printStackTrace() 方法可以分别得到异常对象的额外信息、类名和调用堆栈的信息。并且后一种包含的信息是前一种的超集。

 

来源于 : http://zhidao.baidu.com/question/10487739.html

 

 

 

 

 

 

 

用异常来处理错误

我们总是试图避免在软件程序中错误的发生,但是它的存在却是不幸的实事。无论怎样,如果你能适当的处理错误,将会极大的改善程序的可读性、可靠性以及可维护性。 Java 编程语言使用异常来处理错误。这章主要讲述在什么时候和怎样使用异常来处理错误。

什么是异常?

Java 编程语言使用异常机制为程序提供了错误处理的能力。一个异常是在程序执行期间发生的一个事件,它使用正常的指令流中断。

捕获或指定需求

这段讲述捕获和处理异常。在讨论中包括: try,catch finally 程序块,还有异常链和日志。

怎样抛出异常

这段讲述异常抛出语句和 Throwable 类以及它的子类。

有关未检查的异常争论

因为 Java 编程语言不要求捕获或指定运行时异常或错误的方法,所以程序员会被诱导来编写只抛出运行时异常代码,在这段中我们会解释为什么不应该被诱导。

异常的好处

在这段中,你将会学到更多的使用异常来管理错误优于传统的错误管理技术方面的知识。

什么是异常?

异常( exception )应该是异常事件( exceptional event )的缩写。

异常定义:异常是一个在程序执行期间发生的事件,它中断正在执行的程序的正常的指令流。

当在一个方法中发生错误的时候,这个方法创建一个对象,并且把它传递给运行时系统。这个对象被叫做异常对象,它包含了有关错误的信息,这些信息包括错误的类型和在程序发生错误时的状态。创建一个错误对象并把它传递给运行时系统被叫做抛出异常。

一个方法抛出异常后,运行时系统就会试着查找一些方法来处理它。这些处理异常的可能的方法的集合是被整理在一起的方法列表,这些方法能够被发生错误的方法调用。这个方法列表被叫做堆栈调用( call   stack , 调用方式如下图所示

 

 

 

 

 

 

 

 

运行时系统搜寻包含能够处理异常的代码块的方法所请求的堆栈。这个代码块叫做异常处理器,搜寻首先从发生的方法开始,然后依次按着调用方法的倒序检索调用堆栈。当找到一个相应的处理器时,运行时系统就把异常传递给这个处理器。一个异常处理器要适当地考滤抛出的异常对象的类型和异常处理器所处理的异常的类型是否匹配。异常被捕获以后,异常处理器关闭。如果运行时系统搜寻了这个方法的所有的调用堆栈,而没有找到相应的异常处理器,如下图所示,运行进系统将终止执行。


 

 

 

 

 

 

使用异常来管理错误比传统的错误管理技术有一些优势,你可以“异常的优势”一节学到更多的知识

 

异常管理的优势

你已经读了有关什么是异常以及怎样使用它们的内容,现在是学习在你的程序中使用异常的好处的时候了。

优势 1 :把规则代码与错误处理代码分离

异常处理规定把错误发生时所要的细节工作与程序的主逻辑代码分离。在传统程序中,错误的发现、报告以及处理经常使得代码混乱。例如,思考下面的伪代码,这是一个把整个文件读入内存的方法。

readFile {

open the file;

determine its size;

allocate that much memory;

read the file into memory;

close the file;

}

第一眼看上去,这个函数似乎很简单,但是它却忽略了所发生下面这些错误的可能。

<!-- [if !supportLists]-->1、  <!-- [endif]-->如果不能打开文件,会发生什么?

<!-- [if !supportLists]-->2、  <!-- [endif]-->如果不能判定文件的大小,会发生什么?

<!-- [if !supportLists]-->3、  <!-- [endif]-->如果没有足够的内存,会发生什么?

<!-- [if !supportLists]-->4、  <!-- [endif]-->如果读取失败,会发生什么?

<!-- [if !supportLists]-->5、  <!-- [endif]-->如果文件不能关闭。会发生什么?

要处理这些信息, readFile 函数必须用更多的代码来做错误发现、报告和处理工作。这个函数看上去可能象这样:

errorCodeType readFile {

       initialize errorCode = 0;

       open the file;

       if (theFileIsOpen) {

              determine the length of the file;

              if (gotTheFileLength) {

                     allocate that much memory;

                        if (gotEnoughMemory) {

                                read the file into memory;

                            if (readFailed) {

                                errorCode = -1;

                            }

                          else {

                             errorCode = -2;

                         }

              } else {

                          errorCode = -3;

               }

               close the file;

               if (theFileDidntClose && errorCode == 0) {

                    errorCode = -4;

               } else {

                          errorCode = errorCode and -4;

               }

           } else {

               errorCode = -5;

           }

    return errorCode;

}

 

有如此多的错误发现、报告和返回,使得初的 7 行代码被埋没在混乱的错误代码之中。更严重的是,代码的逻辑流已经没有了,这样使得它很难说明代码是否正在做着正确的事情:如果函数在分配内存过程失败,文件真得的被关闭了吗?甚至更难保证在三个月之后,你编写的这段代码继续做正确的事情。

 

异常处理使你能够编写代码的主工作流并且在别的地方来处理异常信息。如果 readFile 函数使用异常处理来代替传统的错误管理技术,它应该像如下所示的代码这样:

readFile {

    try {

        open the file;

        determine its size;

        allocate that much memory;

        read the file into memory;

        close the file;

    } catch (fileOpenFailed) {

       doSomething;

    } catch (sizeDeterminationFailed) {

        doSomething;

    } catch (memoryAllocationFailed) {

        doSomething;

    } catch (readFailed) {

        doSomething;

    } catch (fileCloseFailed) {

        doSomething;

    }

}

 

注意:异常处理不会节省错误的发现、报告、处理的工作量,但是它们能够帮助你更有效的组织代码。

 

优势 2 :向调用堆栈上层传递错误

异常处理的第二个优势是向方法的调用堆栈上层传递错误报告的能力。假如 readFile 方法是主程序调用的一系列嵌套方法中的第四个方法:方法 1 调用方法 2 ,方法 2 调用方法 3 ,方法 3 调用 readFile ,代码结构如下所示:

method1 {

    call method2;

}

method2 {

    call method3;

}

method3 {

    call readFile;

}

还假如 method1 是唯一的能够处理 readFile 方法中所可能发生的错误的方法,那么传统的错误处理技术会强制 method2 method3 来传递通过 readFile 调用堆栈所返回的错误代码,直到错误代码传递到 method1 -因为只有 method1 能够处理这些错误,其代码结构如下所示:

method1 {

    errorCodeType error;

    error = call method2;

    if (error)

        doErrorProcessing;

    else

        proceed;

}

errorCodeType method2 {

    errorCodeType error;

    error = call method3;

    if (error)

        return error;

    else

        proceed;

}

errorCodeType method3 {

    errorCodeType error;

    error = call readFile;

    if (error)

         return error;

    else

        proceed;

}

 

回忆一下, Java 运行时环境搜寻调用堆栈来查找任意的处理特殊的异常的方法。一个方法能够抛出它内部的任何异常,所以允许一个上层调用堆栈的方法来捕获它。因此只有处理相关错误的方法来处理发现的错误,代码结构如下所示:

method1 {

    try {

        call method2;

    } catch (exception e) {

        doErrorProcessing;

    }

 

}

method2 throws exception {

    call method3;

}

method3 throws exception {

    call readFile;

}

 

无论怎样,就像伪代码所展示的那样,躲避异常需要中间方法做一些工作。任意被检查到的由内部方法的抛出的异常必须在这个方法的 throws 子句中被指定。

 

优势 3 :分组和区分错误类型

 

因为所有在程序内部抛出的异常都是对象,异常的分组或分类是类继承的自然结果。在 Java 平台中一组相关异常类的例子是在 java.io 中定义的 IOException 和它的子类。 IOException 是最普通的 IO 异常管理类,并且它描述了在执行 I/O 操作时所发生的任意的错误类型。它的子类描述了一些特殊的错误。例如, FileNotFoundException 异常类代表不能在本地磁盘上找到一个文件。

一个方法能够编写特殊的异常处理器,使它能够处理非常特殊的异常。 FileNotFoundException 异常类没有子类,因此下面的异常处理器只能处理一种异常类型:

catch (FileNotFoundException e) {

    ...

}

 

一个方法能够基于它的分组或通过在 catch 子句中所指定的任何异常的超类的一般类型来捕获异常。例如,要捕获所有的 I/O 异常,而不管它们的具体类型,就可以在异常处理器中指定一个 IOException 参数:

catch (IOException e) {

    ...

}

 

这个处理器将捕获所有的 I/O 异常,包括 FileNotFoundException,EOFException 等等。你能够通过查询传递给异常处理器的参数找到发生错误的详细信息。例如,打印堆栈执行路线:

catch (IOException e) {

    e.printStackTrace();            // output goes to Sytem.err

    e.printStackTrace(System.out);  // send trace to stdout

}

 

你甚至可以创建一个能够处理任意类型的异常的异常处理器:

catch (Exception e) {    // a (too) general exception handler

    ...

}

 

Exception 类是 Throwable 类结构中的顶级类,因此,这个处理器将捕获除了那些被特定处理器捕获的异常以外的异常。你可能想你的程序是否都是这种处理异常的方法,例如,为用户打印错误消息并且退出。

但是,在大多数情况下,你需要异常处理器来尽可能的处理精确一些。原因是在处理器决定最好的恢复策略之前,必须做第一件是判断发生异常的类型是什么。在没有捕获特定错误的情况下,处理器必须有效的提供任意的可能性。 Exception 处理器是最一般的异常处理器,使用这个处理器使得代码捕获和处理更多的程序员没有预料到的错误倾向,从而使得处理器没有目的性。

 

象我们展示的一样,你能够创建异常组,并且用一般化的方式来处理异常,或者使用特定异常类型来区分异常并且用精确的方式来处理异常。

 

捕获和处理异常

 

这段向说明怎样使用异常处理器的三个组成部分- try,catch finally 块来编写异常处理器。这段最后举一个例子,并且分析在不同的情况下发生了什么。

 

下面的例子定义和实现了一个叫做 ListOfNumbers 的类。在类的构造器中, ListOfNumbers 创建了一个 Vector ,它包含了从 0 9 的十个连续的整数。 ListOfNumbers 类也定义了一个叫 writeList 的方法,这个方法把这个数字列表写入一个叫做 OutFile.txt 的文本文件中。这个例子使用了在 java.io 中定义的输出类,这个类在 I/O :读写这一章中介绍。

 

// 注意 : 这样的设计,这个类不会被编译

import java.io.*;

import java.util.Vector;

 

public class ListOfNumbers {

 

    private Vector victor;

    private static final int SIZE = 10;

 

    public ListOfNumbers () {

        victor = new Vector(SIZE);

        for (int i = 0; i < SIZE; i++) {

            victor.addElement(new Integer(i));

        }

    }

 

    public void writeList() {

        PrintWriter out = new PrintWriter(

                            new FileWriter("OutFile.txt"));

 

        for (int i = 0; i < SIZE; i++) {

            out.println("Value at: " + i + " = " +

                            victor.elementAt(i));

        }

 

        out.close();

    }

}

 

这个例子中的第一行黑体字部分代码调用了一个构造器,这个构造器初始化一个文件输出流。如果这个文件不能被打开,这个构造器会抛出一个 IOException 异常。第二行黑体字部分代码调用一个 Vector 类的 elementAt 方法,如果它的参数值太小(小于零)或太大(大于 Vector 中当前所包含的元素数),那么它会抛出一个 ArrayIndexOutOfBoundsException 异常。

 

如果试图编译 ListOfNumbers 类,编译会打印一个有关被 FileWrite 构造器所抛出的异常的错误消息。这是因为构造所抛出的 IOException 异常是一个编译检查性异常,被 elementAt 方法抛出的 ArrayIndexOutOfBoundsException 异常是一个运行时异常,而 Java 编程语言只要求程序处理编译检查性异常,所以你只能获取一个错误消息。

 

现在随着对 ListOfNumbers 类的熟悉,并且知道异常是在程序中的什么地方抛出的,那么你就可以准备把异常处理器编写到 catch 块来处理那些异常。

 

怎样抛出异常

在你能够捕捉一个异常之前,在程序中的某个地方必须有抛出这个异常的代码在在。任何代码都可以抛出异常:它们可以你自己的代码,也可以是来自于别人所写的包中的代码(例如与 Java 平台一起提供的程序包),或者是 Java 运行时环境。不管抛出什么样的异常,都要使用 throw 语句把异常抛出。

 

你可能已经注意到, Java 平台提供了各种的异常类。所有的这些类都是 Throwable 类的子类,并且它们都允许程序来区分在程序执行期间所发生的各种类型的异常。

 

你也可以创建自己的异常类来描述你编写的类中所发生的问题。实际上,如果你是一个程序包的开发人员,你可能必须创建你自己的异常类的集合,以便于让你的用户来区分在你的程序包中发生的错误是来自己于 Java 平台还是其它的包。

 

你也可以创建异常链,异常链在 Java Standard Edition 1.4 中被引入。更多的信息,请看“异常链”这一节。

 

throw ”语句

所有的方法都使用“ throw ”语句来抛出一个异常。 Throw 语句需要一个单独 throwable 对象,这个对象是任意 Throwable 类的子类。如下类所示:

throw someThrowableObject;

 

让我们在程序的上下文中来看一下 throw 语句。下面的 pop 方法把来自于一个公共堆栈中的一个执行类给删除。这个方法从堆栈上面的元素,并且返回被删除的对象。

public Object pop() throws EmptyStackException {

    Object obj;

 

    if (size == 0) {

        throw new EmptyStackException();

    }

 

    obj = objectAt(SIZE - 1);

    setObjectAt(SIZE - 1, null);

    size--;

    return obj;

}

 

pop 方法检查堆栈上是否有元素。如果堆栈是空的(也就是说它的尺寸等于 0 ), pop 方法就会实例化一个新的 EmptyStackException 对象(它是 java.util 中的一个成员),并且抛出它。在这章的后面一节会解释怎样创建自己的异常类。对于现在,你所需要记住的是你只能抛出继承于 java.lang.Throwable 类的对象。

 

注意, pop 方法的声明中包含了一个 throws 子句。 EmptyStackException 是一个检查性异常,并且 pop 方法没有捕捉这个异常。因此,这个方法必须使用 throws 子名来声明它所抛出的异常的类型。

 

Throwable 类和它的子类

 

继承 Throwable 类的对象包括直接子类(直接继承于 Throwable 类的对象)和间接子类(继承于 Throwable 类的子类的对象)。下图说明了 Throwable 类的层次关系和最主要的一些子类。象你看到的一样, Throws 有两个直接的子类: Error 类和 Exception 类。

 


 

Error

当在 Java 虚拟机中发生动态连接失败或其它的定位失败的时候, Java 虚拟机抛出一个 Error 对象。典型的简易程序不捕获或抛出 Errors 对象。

 

Exception

大多数程序都抛出或捕获衍生于 Exception 类的对象。一个异常表明发生了一个问题,但它不是严重的系统问题。你编定的大多数程序将会抛出或捕获 Exceptions 对象(而不是 Errors 对象)。

 

Java 平台中 Exception 类有许多已经定义了的子类。这些子类说明所发生的异常的各种类型。例如, IllegalAccessException 异常类说明了不能找到一个特殊的方法; NegativeArraySizeException 异常类说明程序试图创建一个带有负尺寸的数组。

 

有一个特殊的 Exception 子类: RuntimeException 。这个子类是在程序运行期间在 Java 虚拟机内部所发生的异常。例如 NullPointerException 类就是一个运行时异常类,在一个方法试图通过一个 null 引用来访问一个对象的成员时会发生这个异常。在 Unchecked Exceptions---The Controversy 这一节中,我们会讨论为什么典型的程序不应该抛出运行时异常或 RuntimException 类的子类异常对象。

 

有争议性的未被检查的异常

因为 Java 编程语言不要求方法一定要捕获或列出运行异常或错误,所以程序员就可能被误导,编写只抛出运行时异常或者使所有的异常子类都继承于 RuntimException 的代码,这两种快捷方式允许程序员编写不用为编译错误而操心的代码,并且也不费神去指定或捕获任何异常。尽管这种方法看上去对程序员很方便,但它回避了捕获或指定必要的东西的意图,并且可能使使用你的类的程序员发生错误。

 

为什么设计者决定强制一个方法指定所有的在它的范围内可能被抛出的未检查异常呢?被一个方法抛出的任何异常都是方法公共编程接口的一部分。方法的调用者必须知道有关这个方法所抛出的异常,以便他们能够针对这些异常决定做什么。这些异常是编写方法的接口差不多,有它们的参数和返回值。

 

接下来你的问题可能是:如果它是这么好的说明了一个方法的 API ,包括它能抛出的异常,那么为什么不也指定运行时异常呢?运行时异常描述的问题是一个设计问题的结果,并且, API 的客户代码不能期望从出错的地方来恢复程序执行或用一些方法来处理它们。这些问题包括算法异常(例如被零除),指针异常(例如通过一个空的引用来访问一个对象),以及索引异常(例如试图通过一个越界的索引来访问一个数组)。运行时异常可能在

程序的任何地方发生,并且在一个典型的程序中可能有很多,因此,在每个方法中不得不添加运行异常来降低程序的透明度,这样,编译器不要求你指定或捕获运行时异常(尽管你可以)。

 

抛出运行时异常( RuntimeException )的一个公共案例就是在用户调用了一个错误的方法的时候。例如,一个方法检查它的参数是否有效,如果一个参数是空( null ),那么这个方法就可能抛出一个 NullPointerException 异常,这是一个不检查异常。

 

一般来说,不抛出运行时异常( RuntimeException )或不创建一个运行时异常( RuntimeException )的子类的原因是:人你不想为指定你的方法所能抛出的异常而操心。

 

一个使用异常的方针是:如果客户能够被期望从一个异常中得到恢复,那么就要使用检查性异常。如果一个客户对于从异常中恢复的程序不能做任何事,那么就可以使用不检查性异常。

 

 

 

来源于 : http://www.javaresearch.org/article/31444.htm

 

  • 大小: 18.2 KB
  • 大小: 22.8 KB
  • 大小: 5.1 KB
分享到:
评论

相关推荐

    WorkerError(解决方案).md

    项目中常见的问题,记录一下解决方案

    2024-2025第一学期一上U1~3.pdf

    2024-2025第一学期一上U1~3.pdf

    Redis详解与常见问题解决方案中文最新版本

    redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sortedset --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。感兴趣的朋友可以过来看看

    ASP+ACCESS航班在线定票系统设计(源代码+论文)(源代码+论文+说明文档).zip

    【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。

    全国月尺度平均气温-Tm-1961-2022-025x025

    全国月尺度平均气温数据集(1961-2022, 0.25° × 0.25°)是一个高分辨率的网格化平均气温数据集,覆盖了中国大陆及周边地区。 该数据集通过科学方法整合气象观测和再分析数据,为气候研究、生态模型、农业生产、以及水资源管理等领域提供了重要支持。 数据下载后可显示详细信息。

    yolo算法-筷子数据集-588张图像带标签-.zip

    yolo系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值

    shell脚本编程实践,分享给有需要的人,仅供参考

    模拟退火算法shell脚本编程实践,分享给有需要的人,仅供参考。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。

    基于PCIe接口的高性能视频编辑系统.docx

    基于PCIe接口的高性能视频编辑系统

    python爬虫入门,分享给有需要的人,仅供参考

    python爬虫入门,分享给有需要的人,仅供参考。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。

    在线音乐网站的设计与实现

    在线音乐网站的设计与实现

    电工与电子技术课程标准.doc

    电工与电子技术课程标准.doc

    1-全国各地级市人口、城镇居民人均可支配收入、进出口总额、社会消费品零售总额2015-2021年-社科数据.zip

    根据搜索结果,以下是一条关于社科数据的内容介绍:本数据集涵盖了2015至2021年间全国各地级市的关键经济指标,包括人口数量、城镇居民人均可支配收入、进出口总额以及社会消费品零售总额。这些数据为研究区域经济发展提供了宝贵的信息资源,来源于各省市统计年鉴及国家统计局的官方数据,确保了数据的权威性和准确性。数据内容全面,缺失值较少,适合用于宏观经济分析、政策评估以及学术研究等多个领域。通过这些数据,研究者可以深入了解中国各地区在不同年份的经济表现和发展趋势。

    SessionStorageError(解决方案).md

    项目中常见的问题,记录一下解决方案

    yolo算法-大卡车数据集-96张图像带标签--卡车.zip

    yolo系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值

    6.html

    6

    [net毕业设计]asp.net教师教学评价分析系统(源代码+论文).zip

    【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。

    IP破解(5):DWC-ddrctl-lpddr54(LPDDR4/4X/5控制器)

    S家LPDDR5/4/4X 控制器,针对功耗、延迟、带宽和面积进行了优化,支持 JEDEC 标准 LPDDR5、LPDDR4 和 LPDDR4X SDRAM。控制器通过 DFI 5.0 接口连接到 S家LPDDR5/4/4X PHY 或其他 LPDDR5/4/4X PHY,以创建一个完整的内存接口解决方案。S LPDDR5/4/4X 控制器包括软件配置寄存器,可通过 AMBA 3.0 APB 接口访问。 // Key Used : DWC-DDRCTL (IP access) // Key Used : DWC-LPDDR54-CONTROLLER (Add-on feature access: DWC LPDDR5/4/4X Controller) 注意:压缩包只有IP使用文档,完整IP及无加密SV代码压缩包有获取方式。

    java桌面小程序,主要为游戏.zip学习资源

    java桌面小程序,主要为游戏.zip学习资源VM

    1-全国各省、市、县农业保险绿色保险收入支出赔付率统计数据2002-2020年-社科数据.zip

    全国各省、市、县农业保险绿色保险收入支出赔付率统计数据集涵盖了2002至2020年间的详细数据。该数据集包含全国31个省、自治区、直辖市的农业保险收入、支出、保险总支出、农业保险规模占比以及农业保险赔付率等关键指标。此外,数据还涉及341个地级市的农业保险收入和支出年度数据,时间跨度从2002年到2020年。特别值得一提的是,数据中还包括了县级政府农业保险补贴数据,覆盖了产粮大县726个和非产粮大县755个,时间范围为2016至2018年。这些数据均来源于历年中国保险年鉴,并经过手工整理,提供了农业保险规模占比与农业保险赔付率等重要指标。此数据集为研究中国农业保险市场的发展、政策效果评估以及风险管理提供了宝贵的实证资料。

    中医诊所系统,WPF.zip

    中医诊所系统,WPF.zip

Global site tag (gtag.js) - Google Analytics