java为什么抛出方法签名的一部分
为什么方法上的throws
是其签名的一部分?把它包括在内似乎很奇怪。下面是一个例子,它阻碍了:
@Overide
public void foo() {
throw new UnsupportedOperationException();
}
如果有人从外部看到这个方法,他们可能会在不知道它不受支持的情况下尝试使用它。他们只会在尝试运行代码时学习
但是,如果他们可以这样做,他们会通过查看该方法知道它不受支持,并且如果UnsupportedOperationException
没有扩展RuntimeException
,他们将得到编译错误。EDIT1:但这是不可能的,因为throws
是签名的一部分,所以重写将不起作用
@Overide
public void foo() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
这个问题与Java的设计有关,所以我知道如果没有一个研究Java的人来回答这个问题,可能很难回答,但我希望这个问题以前有人问过他们,或者有一个明显的理由用这种方式来解释原因
# 1 楼答案
throws
部分并不表示抛出所述异常需要该方法,即使在特定情况下也是如此。它只告诉函数允许这样做因此,包含
throws UnsupportedOperationException
并不意味着该方法不受支持。除此之外UnsupportedOperationException
是一个RuntimeException
,所以一个方法可以throw
不管怎样现在,出于在方法签名中需要它的原因,它可以归结为检查异常的能力。为了让编译器能够决定一个方法是否只能抛出指定的异常,它必须能够决定它调用的方法不能抛出未捕获的异常
例如,这意味着重写一个方法意味着您不能添加可能抛出的异常,否则您将无法验证调用该方法的方法不能抛出它指定以外的任何异常。另一种方法是可能的(但我不确定Java是否支持),用可能不会抛出的方法覆盖可能抛出的方法
例如:
现在},但在调用}。这就是为什么
frob
被指定为可能仅throw
{this.fubar
时,可能会抛出其他内容,但fubar
被定义为可能仅throw
{D.fubar
是一个无效的重写,因为这将打开this.fubar
实际抛出ExceptionB
的可能性,并且编译器无法保证frob
不会抛出ExceptionB
# 2 楼答案
没有人提到的一件事是对你的问题的一个非常重要的回答:
该
throws
不是方法签名的一部分JLS 8.4.2. Method Signature非常清楚地表明:
这正是
throws
设计为在编译时检查所有检查异常的主要原因-该方法的客户端将知道该方法可能抛出什么检查异常被强制处理或指定抛出(但此规范不是方法签名的一部分)
未检查的异常不必处理或指定抛出,而且Oracle's tutorial善于解释原因:
# 3 楼答案
未检查的异常是
RuntimeException
的子类,您不必添加抛出声明。所有其他异常都必须在方法体中处理,要么使用try/catch语句,要么使用throws声明未检查异常的示例:
IllegalArgumentException
,有时用于通知使用非法参数调用了方法。不需要投掷检查异常的示例:
IOException
来自java的一些方法。io包可能会抛出。对方法声明使用try/catch或add抛出IOException,并将异常处理委托给方法调用方