为了账号安全,请及时绑定邮箱和手机立即绑定

为什么编译器允许抛射,而方法永远不会抛出异常

为什么编译器允许抛射,而方法永远不会抛出异常

撒科打诨 2022-09-01 19:53:41
我想知道为什么java编译器允许在方法声明中抛出,而方法永远不会抛出异常。因为“throws”是处理异常的一种方式(告诉调用方处理它)。由于有两种处理异常的方法(throws和try/catch)。在 try/catch 中,它不允许捕获未在 try 块中引发的异常,但它允许在可能不会引发异常的方法中引发。private static void methodA() {    try {        // Do something        // No IO operation here    } catch (IOException ex) {  //This line does not compile because                              //exception is never thrown from try        // Handle       }}private static void methodB() throws IOException { //Why does this //compile when excetion is never thrown in function body    //Do Something     //No IO operation}
查看完整描述

3 回答

?
芜湖不芜

TA贡献1796条经验 获得超7个赞

该条款是该方法合同的一部分。它要求方法的调用方表现得好像指定的异常可能由该方法引发(即捕获异常或声明自己的子句)。throwsthrows


方法的初始版本可能不会引发子句中指定的异常,但将来的版本可以在不破坏API的情况下引发它(即调用该方法的任何现有代码仍将通过编译)。throws


反之亦然。如果用于引发子句中指定的异常的方法,但其将来的版本不再引发该异常,则应保留该子句,以免破坏使用方法的现有代码。throwsthrows


第一个示例:


假设您有此代码,它使用:methodB


private static void methodA() {

    methodB(); // doesn't have throws IOException clause yet

}

如果以后要改成 throw ,将停止传递编译。methodBIOExceptionmethodA


第二个例子:


假设您有此代码,它使用:methodB


private static void methodA() {

    try {

        methodB(); // throws IOException

    }

    catch (IOException ex) {


    }

}

如果从 的未来版本中删除该子句,将不再通过编译。throwsmethodBmethodA


当 is 时,此示例不是很有趣,因为它只能在本地使用(在同一类中,可以轻松地修改调用它的所有方法)。methodAprivate


但是,如果它变成 ,则您不知道谁使用(或将使用)您的方法,因此您无法控制由于添加或删除子句而可能中断的所有代码。publicthrows


如果它是一个实例方法,那么即使您不引发异常,也允许该子句的另一个原因 - 该方法可以被重写,并且重写方法可能会引发异常,即使基类实现没有。throws


查看完整回答
反对 回复 2022-09-01
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

因为签名定义了方法的协定。即使该方法现在没有抛出IOException,也许将来会抛出IOException,并且您希望为这种可能性做好准备。

假设您现在只是为该方法提供了一个虚拟实现,但是您知道,稍后,实际的实现可能会引发 IOException。如果编译器阻止您添加此 throws 子句,则在提供该方法的实际实现后,您将被迫(递归地)对该方法的所有调用进行返工。


查看完整回答
反对 回复 2022-09-01
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

  1. 方法 B 会引发 IOException,因此方法调用 methodB 负责捕获将由 methodB 引发的异常。尝试从其他方法调用方法B,它会要求您捕获它或重新抛出IOException。在某个地方,你将不得不在链中捕获IOException(在try/catch块中)。所以你不会得到编译时错误

    private void sampleMethod(){ try { methodB(); } catch (IOException e) { // TODO Auto-generate catch block e.printStackTrace(); } }

  2. 方法A 中的 try/catch 诚然会吞并异常,这意味着方法 A 负责捕获 try/catch 块中的异常。“任何java程序中的每个语句都必须是可访问的,即每个语句必须至少可执行一次”因此,您将收到编译器错误,因为您的try块没有任何代码来导致IOException。


查看完整回答
反对 回复 2022-09-01
  • 3 回答
  • 0 关注
  • 169 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号