为什么抛出方法签名的一部分

Fro*_*gon 7 java methods exception method-signature

为什么抛出一个方法部分的签名.包含它似乎很奇怪.这是一个阻碍它的例子.

@Overide
public void foo() {
    throw new UnsupportedOperationException();
}
Run Code Online (Sandbox Code Playgroud)

如果有人从外面看到这种方法,他们可能会尝试使用它而不知道它不受支持.他们只会在尝试运行代码时学习它.

但是,如果他们可以做这样的事情,他们会通过查看不受支持的方法知道,如果UnsupportedOperationException没有扩展RuntimeException,他们会得到编译错误.编辑1:但这是不可能的,因为抛出是签名的一部分,因此覆盖将不起作用.

@Overide
public void foo() throws UnsupportedOperationException {
    throw new UnsupportedOperationException();
}
Run Code Online (Sandbox Code Playgroud)

这个问题与Javas的设计有关,所以我知道如果没有一个人在其上工作并且回答它可能很难回答,但是我希望可能之前已经向他们提出这个问题或者可能存在明显的理由是这样解释原因.

sky*_*ing 6

throws部分并不表示该方法需要抛出所提到的异常,即使在特定的时候也是如此.它只告诉该函数允许这样做.

因此,包括throws UnsupportedOperationException将不意味着该方法不受支持.除此之外,无论如何UnsupportedOperationException都是一种RuntimeException方法throw.

现在因为在方法的签名中需要它,它归结为完全检查异常的能力.为了使编译器能够确定方法是否只能抛出指定的异常,它必须能够确定它调用的方法不能抛出未捕获的异常.

这意味着,例如,覆盖方法意味着您无法添加可能引发的异常,否则您将无法验证调用该方法的方法是否不会抛出除指定之外的任何内容.另一种方式是可能的(但我不确定Java是否支持),覆盖一个可能抛出一个可能不抛出的方法.

例如:

class B {
    int fubar(int) throws ExceptionA {
    }

    int frob(int) throws ExceptionA {
         return fubar(int);
    }
}

class D extends B {
    int fubar(int) throws ExceptionB {
    }
}
Run Code Online (Sandbox Code Playgroud)

现在frob可能throw只被指定ExceptionA,但在调用this.fubar它时会打开抛出其他东西的可能性,但fubar可能只是被定义throw ExceptionA.这就是为什么这D.fubar是一个无效的覆盖,因为这会打开this.fubar实际抛出的可能性,ExceptionB编译器将无法保证frob不抛出ExceptionB.