例如如下代码:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
Date date = sdf.parse("abcd");
这段代码会抛出ParseException,而它是编译时异常,为什么编译阶段不报错,运行时报错?
例如如下代码:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
Date date = sdf.parse("abcd");
这段代码会抛出ParseException,而它是编译时异常,为什么编译阶段不报错,运行时报错?
首先,我们需要澄清一点:在Java中,ParseException
并不是编译时异常(checked exception),而是运行时异常(unchecked exception)。编译时异常是指那些必须在编译时被捕获或者声明的异常,这些异常都是 Exception
类(或其子类,但非 RuntimeException
或其子类)的直接或间接子类,并且没有被标记为 @FunctionalInterface
注解的方法中的 lambda 表达式或方法引用所抛出。
对于 ParseException
,它是 java.text.ParseException
类的一个实例,该类继承自 java.lang.Exception
而非 java.lang.RuntimeException
。然而,Java设计者选择让 ParseException
成为一个运行时异常,这意味着它不需要在代码中显式捕获或声明。这种设计选择是为了简化API的使用,因为对于许多文本解析操作,解析失败是常见的运行时情况,而不是编程错误。
现在,让我们回到你的问题:为什么 ParseException
在编译阶段不报错,而在运行时报错?
原因是 ParseException
是一个运行时异常,编译器不会强制你捕获或声明它。这意味着你可以编写代码来调用可能抛出 ParseException
的方法,而无需在调用代码中包含任何异常处理代码。然而,当这段代码运行时,如果实际上发生了 ParseException
(例如,在你的例子中,尝试将字符串 "abcd" 解析为日期时),Java运行时环境将抛出一个 ParseException
异常,这通常会导致程序的中断(除非有某种形式的异常处理来捕获并处理它)。
为了处理这种运行时异常,你可以使用 try-catch
块来捕获 ParseException
并相应地处理它。但是,由于 ParseException
是一个运行时异常,所以这不是必须的。
以下是处理 ParseException
的一个示例:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
try {
Date date = sdf.parse("abcd");
} catch (ParseException e) {
e.printStackTrace(); // 或者其他异常处理逻辑
}
在这个例子中,我们使用了 try-catch
块来捕获并处理 ParseException
。但是,请注意,即使我们没有这个 try-catch
块,代码也能成功编译,因为它不是编译时异常。
有个错误说法:继承RuntimeExcetion的是运行时异常,继承Exception的是编译时异常。
只是在编译阶段,对RuntimeExcetion以及子类有点特殊处理,不检查你有没有写try catch
。
编译异常与运行时异常,是一种描述,跟具体类没有关系。Exception那么多子类,带Parse的,应该都是运行时参数不对才会报错。
我们可以认为全都是Exception。他的那么多子类是为不同场景使用时好区分堆栈信息,让你一眼看出代码哪个地方出问题了。一般业务开发的时候,我们也会定义一个或多个自己的某业务专用异常。
其实不用纠结编译时运行时,把所有异常都按需处理好才是正确稳妥的。
JAVA里的受检性异常,也就是你说的编译时异常,意思是在编译时期(也就是你写代码的时候)要求程序员对可能发生的异常作出处理,你可以try..catch..处理也可以直接throws异常处理(如果你选择二者都不做,就会提示异常,如图),但是并不是说程序员作的处理就一定不会导致异常的发生。
也就是说编译时异常需要你强制性对代码风险做一定规范,但是不能在编译时期就对你作出的处理就作出是否会导致异常的判断,如果你处理的有问题,该怎么导致异常还是会怎么导致异常。
3 回答2.6k 阅读✓ 已解决
3 回答4.1k 阅读✓ 已解决
8 回答3.6k 阅读
4 回答2.8k 阅读✓ 已解决
2 回答2.7k 阅读✓ 已解决
3 回答2.5k 阅读✓ 已解决
3 回答1.7k 阅读✓ 已解决
你对编译时异常理解错误了,实际上这种异常学名叫受检异常,意思是,你写的这段代码,可能会发生这个异常,你需要进行预判,检查它,当错误发生后,做一个什么样的处理,这种错误是需要你必须去关注的。它在运行时,可能会发生也可能不会发生异常,是一种编码的预判行为。
至于编译阶段不报错,是因为编译的时候,代码都没运行呢,怎么给你报错,换个理解方式吧。