java.lang.RuntimeException和java.lang.Exception之间的区别

时间:2010-02-03 06:39:47

标签: java exception

有人请解释java.lang.RuntimeExceptionjava.lang.Exception之间的区别吗?如果我创建自己的异常,如何决定扩展哪一个?

12 个答案:

答案 0 :(得分:164)

在Java中,有两种类型的例外:已检查异常和未经检查的异常。必须由代码显式处理已检查的异常,而不需要显式处理未经检查的异常。

对于已检查的异常,您必须在可能引发异常的代码周围放置一个try / catch块,或者向该方法添加“throws”子句,以指示该方法可能抛出此类异常(必须在调用类或以上处理。)

从“Exception”派生的任何异常都是一个已检查的异常,而未检查从RuntimeException派生的类。调用代码不需要显式处理RuntimeExceptions。

答案 1 :(得分:144)

通常 RuntimeExceptions 是可以通过编程方式阻止的例外。 E.g NullPointerExceptionArrayIndexOutOfBoundException。如果在调用任何方法之前检查null,则NullPointerException将永远不会发生。类似地,如果首先检查索引,则永远不会发生ArrayIndexOutOfBoundException。编译器不会检查RuntimeException,因此它是干净的代码。

编辑:这些天人们赞成RuntimeException,因为它产生了干净的代码。这完全是个人选择。

答案 2 :(得分:78)

在查看java.lang.RuntimeExceptionjava.lang.Exception类之间的区别之前,您必须知道Exception层次结构。 ExceptionError类都派生自类Throwable(派生自类Object)。课程RuntimeException派生自班级Exception

所有例外都来自ExceptionRuntimeException

源自RuntimeException的所有异常都称为 未经检查 例外。所有其他例外情况都是 已检查 例外。必须在代码中的某处捕获已检查的异常,否则将无法编译。这就是为什么它们被称为检查异常。另一方面,对于未经检查的异常,调用方法没有义务处理或声明它。

因此,编译器强制您处理的所有异常都直接派生自java.lang.Exception,编译器不强制您处理的所有其他异常都派生自java.lang.RuntimeException

以下是RuntimeException的一些直接已知子类。

AnnotationTypeMismatchException,
ArithmeticException,
ArrayStoreException,
BufferOverflowException,
BufferUnderflowException,
CannotRedoException,
CannotUndoException,
ClassCastException,
CMMException,
ConcurrentModificationException,
DataBindingException,
DOMException,
EmptyStackException,
EnumConstantNotPresentException,
EventException,
IllegalArgumentException,
IllegalMonitorStateException,
IllegalPathStateException,
IllegalStateException,
ImagingOpException,
IncompleteAnnotationException,
IndexOutOfBoundsException,
JMRuntimeException,
LSException,
MalformedParameterizedTypeException,
MirroredTypeException,
MirroredTypesException,
MissingResourceException,
NegativeArraySizeException,
NoSuchElementException,
NoSuchMechanismException,
NullPointerException,
ProfileDataException,
ProviderException,
RasterFormatException,
RejectedExecutionException,
SecurityException,
SystemException,
TypeConstraintException,
TypeNotPresentException,
UndeclaredThrowableException,
UnknownAnnotationValueException,
UnknownElementException,
UnknownTypeException,
UnmodifiableSetException,
UnsupportedOperationException,
WebServiceException 

答案 3 :(得分:40)

检查异常,并取消选中RuntimeException。

Checked意味着编译器要求您在catch中处理异常,或者将您的方法声明为抛出它(或其中一个超类)。

通常,如果期望API的调用者处理异常,则抛出一个已检查的异常;如果是调用者通常无法处理的异常,则抛出一个未经检查的异常,例如其中一个参数的错误,即编程错误。

答案 4 :(得分:15)

运行时异常类(RuntimeException及其子类)免于编译时检查,因为编译器无法确定不会发生运行时异常。 (来自JLS)。

在您设计的类中,您应该继承 Exception 并抛出实例 它表示任何特殊情况。这样做,你将明确地发出信号 你的班级的客户可能会抛出异常,他们必须这样做 采取措施处理这些特殊情况。

以下代码段解释了这一点:

//Create your own exception class subclassing from Exception
class MyException extends Exception {
    public MyException(final String message) {
        super(message);
    }
}

public class Process {
    public void execute() {
        throw new RuntimeException("Runtime");
    }  
    public void process() throws MyException {
        throw new MyException("Checked");
    }
}

在上面的类 Process 的类定义中,方法execute可以 抛出 RuntimeException ,但方法声明无需指定 它抛出 RuntimeException

方法process抛出一个已检查的异常,它应该声明它 将抛出一个已检查的异常 MyException 而不会这样做 编译错误。

上面的类定义也会影响使用 Process 类的代码。

调用new Process().execute()是一个有效的调用,作为表单的调用 new Process().process()给出了编译错误。这是因为客户端代码应该 采取措施处理MyException(可以包含对process()的调用 一个try / catch块。)

答案 5 :(得分:10)

Proper use of RuntimeException?

来自Unchecked Exceptions -- The Controversy

  

如果可以合理地预期客户   从异常中恢复,成功   检查的例外。如果是客户   无法从中恢复过来   例外,让它不受控制   异常。

请注意,未经检查的异常是从RuntimeException派生的异常,而已检查的异常是从Exception派生的异常。

如果客户端无法执行任何操作以从异常中恢复,为什么抛出RuntimeException?文章解释说:

  

运行时异常代表问题   这是编程的结果   问题,以及API客户端   代码不能合理地预期   从中恢复或处理它们   无论如何。这些问题包括   算术异常,例如   除以零;指针异常,   例如尝试访问对象   通过空引用;和索引   异常,例如尝试   通过一个访问数组元素   索引太大或太小。

答案 6 :(得分:4)

来自oracle文档:

  

这是底线指南:如果客户可以合理地   期望从异常中恢复,使其成为检查异常。如果   客户端无法做任何事情从异常中恢复,使其成为一个   未经检查的例外。

运行时异常表示由编程问题导致的问题,因此,无法合理地期望API客户端代码从它们中恢复或以任何方式处理它们。

RuntimeExceptions类似于“无效使用api的异常”runtimeexceptions示例:IllegalStateException,NegativeArraySizeException,NullpointerException

使用Exceptions,您必须明确地捕获它,因为您仍然可以执行某些操作来恢复。异常的示例有:IOException,TimeoutException,PrintException ...

答案 7 :(得分:4)

简单来说,如果您的客户/用户可以从异常中恢复,那么将其设为已检查 异常,如果您的客户端无法执行任何操作从例外,然后将其设为未选中 RuntimeException 。例如,RuntimeException将是一个编程错误,比如除零,没有用户可以对程序员本人做任何事情,那么它就是 RuntimeException

答案 8 :(得分:3)

RuntimeException是Exception类的子类

这是Exception类的许多子类之一。 RuntimeException是在Java虚拟机的正常操作期间可以抛出的那些异常的超类。不需要方法在其throws子句中声明RuntimeException的任何子类,这些子类可能在方法执行期间被抛出但未被捕获。

hierchy是

java.lang.Object中

--- java.lang.Throwable中

------- java.lang.Exception的

-------------了java.lang.RuntimeException

答案 9 :(得分:0)

异常是处理应用程序流中意外事件的好方法。编译器未选中RuntimeException,但您可能更喜欢使用扩展Exception类的Exceptions来控制api客户端的行为,因为它们需要捕获错误以便编译它们。也形成了良好的文档。

如果想要实现干净的接口,请使用继承来子类化应用程序具有的不同类型的异常,然后公开父异常。

答案 10 :(得分:0)

有两种类型的异常,如果出现这种异常,可以从已检查的异常中恢复。运行时异常是不可恢复的,运行时异常是编程错误,程序员在编写代码时应该处理它,并且继续执行此操作可能会给您不正确的结果。运行时异常是违反前提条件的。你有一个大小为10的数组,并且你试图访问第11个元素,它将抛出ArrayIndexOutOfBoundException

答案 11 :(得分:0)

  1. 用户定义的异常可以是Checked Exception或Unchecked Exception,它取决于它所扩展的类。

  2. 用户定义的异常可以是自定义检查异常,如果它扩展到异常类

  3. 用户定义的异常可以是自定义未经检查的异常,如果它扩展到运行时异常类。

  4. 定义一个类并使其成为异常或运行时异常的子项