运行时异常表示代码存在错误(例如NPE),如果代码没有错误,则绝不应抛出。它总是指示代码中的错误(与断言相同,但断言用于内部类错误,而运行时异常用于类的客户端错误)。
运行时异常不应该被捕获。
另一方面,检查异常是方法签名的一部分,应该被捕获和处理。它们可能表示用户输入错误或外部资源问题(如IOException
)。
尽管如此,我也不明白为什么NumberFormatException
是运行时异常?
运行时异常表示代码存在错误(例如NPE),如果代码没有错误,则绝不应抛出。它总是指示代码中的错误(与断言相同,但断言用于内部类错误,而运行时异常用于类的客户端错误)。
运行时异常不应该被捕获。
另一方面,检查异常是方法签名的一部分,应该被捕获和处理。它们可能表示用户输入错误或外部资源问题(如IOException
)。
尽管如此,我也不明白为什么NumberFormatException
是运行时异常?
首先,告诉你
运行时异常不应该被捕获
的人对Java了解很少。不要听他们的 - 他们是错的。
NumberFormatException是一个运行时异常:选择未检查的异常是因为它们指示了一个编程错误。在调用Integer.parseInt()
(例如)之前,可能已经知道一个字符串是一个有效的整数,例如这里有一种方法:
if (str.matches("^\\d{1,8}$") {
int myInt = Integer.parseInt(str); // will never throw NumberFormatException
}
因此,可以认为得到一个空指针是一种编程错误 - 程序员选择了在使用前不先检查它。如果您不确定要解析的字符串的完整性/质量,那么很容易捕获。try {
// parse your string
} catch (NumberFormatException e) {
// do something about it
}
将其作为运行时的另一个原因是,如果你确信不会出现异常(例如完全信任String数据的来源),它不会用潜在的不必要try/catch
块混淆代码。
URLFormatThingyException
之类的已检查异常也可以这样说。简而言之,这整个情况有点混乱。 - Bart van HeukelomInteger.parseInt("-1"); // D'oh!
- 不要在你的代码中重复解析代码,这样做会打败库的整个目的。空值检查很简单,所以它们是允许的(在一定程度上)。Jörn的答案建议改用文本解析API,这在这种情况下似乎更合适。 - CurtainDogNumberFormatException
可能在解析配置文件时抛出,这种情况下属于程序员错误。当解析用户输入时,通常使用会抛出已检查的 ParseException
的 NumberFormat
。
NumberFormatException是IllegalArgumentException的子类。这是一个运行时异常的原因是,完全有可能违反接受String并返回Number的方法的契约。如果我传入123D
,而数据没有得到适当的验证,那么这将是一个合适的非法参数。
NumberFormatException
是一种编译时异常。但它不是由Java编译器抛出的,而是在程序运行时由格式化字符串解析器/编译器抛出的。同样适用于Pattern
和其他正则表达式的使用方式;你的程序正在运行解析器/编译器。我认为运行时异常是指计算机硬件执行某个操作后,意识到这是不可能的,因此无法回退并抛出异常,导致程序崩溃。例如数字格式异常,计算机试图将字符串读取为整数。硬件尝试将字符存储在整数变量中,这是不可能的。基本上任何涉及硬件的事情,比如除以0。