java.lang.RuntimeException和java.lang.Exception之间的区别
有人请解释java.lang.RuntimeException
和java.lang.Exception
之间的区别吗? 如果我创build自己的exception,如何决定扩展哪一个?
通常, RuntimeExceptions是可以通过编程方式阻止的exception 。 例如NullPointerException
, ArrayIndexOutOfBoundException
。 如果您在调用任何方法之前检查null
,则绝不会发生NullPointerException
。 同样,如果首先检查索引, ArrayIndexOutOfBoundException
永远不会发生。 RuntimeException
不被编译器检查,所以它是干净的代码。
编辑 :现在人们赞成RuntimeException
因为它产生的干净的代码。 这完全是个人select。
在Java中,有两种types的exception:检查exception和未检查exception。 检查的exception必须由代码显式处理,而未检查的exception不需要明确处理。
对于检查的exception,你必须在可能抛出exception的代码周围放置一个try / catch块,或者向该方法添加一个“throws”子句,以指示该方法可能抛出这种types的exception在通话class或以上处理)。
从“Exception”派生的任何exception都是检查的exception,而从RuntimeException派生的类未被检查。 RuntimeExceptions不需要由调用代码明确处理。
在查看java.lang.RuntimeException
和java.lang.Exception
类之间的区别之前,您必须知道Exception
层次结构。 Exception
和Error
类都是从Throwable
类派生的(派生自类Object
)。 而类RuntimeException
是从Exception
类派生的。
所有exception都来自Exception
或RuntimeException
。
所有从RuntimeException
派生的exception都称为未经检查的exception。 而所有其他的例外是检查的例外。 检查的exception必须在代码中的某处被捕获,否则将不会被编译。 这就是为什么他们被称为检查exception。 另一方面,没有检查的例外,调用方法没有义务处理或声明它。
因此,所有编译器强制处理的exception都是直接从java.lang.Exception
派生出来的,编译器不强制处理的所有其他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
一个exception被选中,并且RuntimeException未被选中。
Checked意味着编译器要求你在catch中处理exception,或者声明你的方法是抛出它(或者它的一个超类)。
通常,如果API的调用者需要处理该exception,则抛出一个checkedexception;如果调用者不能正常处理,则抛出一个未经检查的exception,例如一个参数错误,即一个编程错误。
运行时exception类(RuntimeException及其子类)免于编译时检查,因为编译器无法确定运行时exception不会发生。 (来自JLS)。
在你devise的类中,你应该子类Exception并抛出它的实例来指示任何特殊的场景。 这样做,你会明确地告诉你的类的客户,你的类的使用可能会抛出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
抛出一个检查的exception,它应该声明它会抛出exceptiontypesexception的检查exception,而不是这样做将是一个编译错误。
上面的类定义将影响使用Process类的代码。
调用new Process().execute()
是一个有效的调用,因为调用new Process().process()
会导致编译错误。 这是因为客户端代码应该采取措施来处理MyException
(比如调用process()可以放在try / catch块中)。
正确使用RuntimeException?
从未经检查的例外 – 争议 :
如果客户可以合理预期从exception中恢复,请将其作为检查exception。 如果客户端无法做任何事情来恢复exception,使其成为一个unchecked例外。
请注意,未经检查的exception是从RuntimeException
派生的Exception
并且检查的exception是从Exception
派生的Exception
。
为什么抛出一个RuntimeException
如果客户端不能做任何事情来恢复exception? 文章解释说:
运行时exception表示由于编程问题而导致的问题,因此API客户端代码不能合理地从它们中恢复或以任何方式处理它们。 这样的问题包括算术例外,例如除以零; 指针exception,比如试图通过空引用访问一个对象; 和索引exception,比如试图通过太大或太小的索引访问数组元素。
从oracle文档:
以下是底线指导原则:如果客户可以合理预期从exception中恢复,请将其作为检查exception。 如果客户端无法做任何事情来恢复exception,使其成为一个unchecked例外。
运行时exception表示由于编程问题而导致的问题 ,因此API客户端代码不能合理地从它们中恢复或以任何方式处理它们。
RuntimeExceptions就像“exception使用apiexception”的runtimeexceptions的例子:IllegalStateException,NegativeArraySizeException,NullpointerException
有了例外,你必须明确地捕捉到它,因为你仍然可以做一些事情来恢复。 exception的例子有:IOException,TimeoutException,PrintException …
RuntimeException是Exception类的子类
这是Exception类的许多子类之一。 RuntimeException是在Java虚拟机正常运行期间可以抛出的那些exception的超类。 方法不需要在throws子句中声明RuntimeException的任何子类,这些子类可能在方法执行期间被抛出,但是没有被捕获。
hierchy是
java.lang.Objectinheritance
— java.lang.Throwable中
——- java.lang.Exception的
————-了java.lang.RuntimeException
简单的说,如果你的客户端/用户可以从exception中恢复,那么把它设为一个Checked Exception ,如果你的客户端不能做任何事情来从exception中恢复,那么使它成为Unchecked RuntimeException 。 例如,一个RuntimeException将是一个编程错误,就像被零除,没有用户可以对它做任何事情,但程序员自己,那么这是一个RuntimeException 。
例外是处理应用程序stream程中意外事件的好方法。 RuntimeException没有被编译器选中,但是您可能更喜欢使用扩展Exception Class的exception来控制api客户端的行为,因为它们需要捕获错误以供它们编译。 也形成很好的文档。
如果要实现干净的接口,使用inheritance来inheritance应用程序所具有的不同types的exception,然后公开父exception。
有两种types的exception,如果遇到这种exception,您可以从检查的exception中恢复。 运行时exception是不可恢复的,运行时exception是编程错误,编程人员在编写代码时应该照顾它,并继续执行这可能会给你不正确的结果。 运行时exception是关于违反前置条件。 你有一个大小为10的数组,你试图访问第11个元素,它会抛出ArrayIndexOutOfBoundException
- “鸭子例外”是什么意思?
- 为什么是exception.printStackTrace()被认为是不好的做法?
- 从std :: cout或std :: ofstream(file)获取一个std :: ostream
- 在没有例外的情况下,C ++exception以何种方式减慢代码?
- 我的方法应抛出自己的exception,或让.NET抛出,如果文件不存在?
- Python:我怎么知道哪些exception可能会从方法调用中抛出
- 在使用Python with语句时捕捉exception
- devise模式:exception/error handling
- IntelliJ中是否有“Break on Exception”?