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
TA贡献1875条经验 获得超3个赞
因为签名定义了方法的协定。即使该方法现在没有抛出IOException,也许将来会抛出IOException,并且您希望为这种可能性做好准备。
假设您现在只是为该方法提供了一个虚拟实现,但是您知道,稍后,实际的实现可能会引发 IOException。如果编译器阻止您添加此 throws 子句,则在提供该方法的实际实现后,您将被迫(递归地)对该方法的所有调用进行返工。
TA贡献1813条经验 获得超2个赞
方法 B 会引发 IOException,因此方法调用 methodB 负责捕获将由 methodB 引发的异常。尝试从其他方法调用方法B,它会要求您捕获它或重新抛出IOException。在某个地方,你将不得不在链中捕获IOException(在try/catch块中)。所以你不会得到编译时错误。
private void sampleMethod(){ try { methodB(); } catch (IOException e) { // TODO Auto-generate catch block e.printStackTrace(); } }
方法A 中的 try/catch 诚然会吞并异常,这意味着方法 A 负责捕获 try/catch 块中的异常。“任何java程序中的每个语句都必须是可访问的,即每个语句必须至少可执行一次”因此,您将收到编译器错误,因为您的try块没有任何代码来导致IOException。
添加回答
举报
