什么时候必须在方法声明中使用 "throws" 字?

When I must use the "throws" word in declaration of a method?

我知道这很简单,但作为 java 的新手,我有问题!

这是一个简单的 Java 卡片小程序 returns SW=0xEE 0xFF 在收到任何命令时:

package secondStep; 
import javacard.framework.*;

public class BadRepeater extends Applet
{
    public static void install(byte bArray[], short bOffset, byte bLength) throws ISOException 
    {
        new BadRepeater().register();
    }

    public void process(APDU arg0) throws ISOException 
    {
        ISOException.throwIt((short)0xeeff);
    }  
}

我从 process 方法声明行的末尾删除了单词 throws ISOException :

package secondStep; 
import javacard.framework.*;

public class BadRepeater extends Applet
{
    public static void install(byte bArray[], short bOffset, byte bLength) throws ISOException 
    {
        new BadRepeater().register();
    }

    public void process(APDU arg0) 
    {
        ISOException.throwIt((short)0xeeff);
    }  
}

以上两个程序都可以正常工作。

问题是"what is the difference?"

什么时候必须在行尾使用 throws ... 一词,什么时候不需要?

ISOException 是 RuntimeException 的子类,因此它不是已检查的异常,因此不需要 throws 子句。

您必须仅声明已检查的异常。您可以声明未经检查的异常,以表明它们可能会被抛出。

例如 parseInt(String s) 声明它抛出一个 NumberFormatException,即使它没有被检查,因为它很可能会这样做(传递它而不是一个数字是一种常见的情况)。

来自文档(强调我的):

Runtime exceptions can occur anywhere in a program, and in a typical one they can be very numerous. Having to add runtime exceptions in every method declaration would reduce a program's clarity. Thus, the compiler does not require that you catch or specify runtime exceptions (although you can).

异常继承

是否检查异常取决于它扩展/实现的内容。

所有意外事件的根源是Throwable界面。有ThrowableErrorException两种。

Error 用于致命的 JVM 事件,例如 ThreadDeath。您很少需要处理这些事件,因此将它们分开。

Exception 是所有异常的根类型,检查和未检查。将检查扩展 Exception 而不是 RuntimeException 的异常。

RuntimeException 扩展 Exception 并允许取消选中。

ISOException 未选中,因此扩展了 RuntimeException(或者它是 parent/grandparent/etc)。在这种情况下,它扩展 CardRuntimeException 扩展 RuntimeException (based on the Javadoc I found)

当以下两个条件都成立时,您必须使用 throw

  • 声明的异常 不是 来自 RuntimeException,
  • 您的方法中有一个代码路径 throw 存在该异常,或者在 throws 声明中调用具有该异常的方法。

ISOException不符合第一个条件,因为它派生自RuntimeException。因此,它的声明是可选的。

请注意,添加 throws 是一项重大更改,因为调用您的方法的代码需要捕获您的异常。这就是为什么您可以为您从未真正 throw 添加 throws 的原因,以便您稍后可以为其添加 throw

如果方法抛出的异常是已检查异常,则您只需在方法中包含 "throws" 子句。如果方法抛出运行时异常,则可选。在这种情况下,ISOException is a runtime exception,两个程序都可以正常工作。

问候

普遍的共识似乎是当您期望抛出异常时,您应该在方法的Java文档中记录异常。 RuntimeExceptions 也是如此。您可以使用 @throws.

记录它们

在Java卡很多例外也带一个reason(短)。在这些情况下,您应该清楚地指出可以生成哪些原因代码(使用列表,在 HTML 中使用标签 <ul><ol> 并且每个项目都有一个 <li> )。对于 ISOException 实例,原因代码将被转换为 ISO 7816 状态字(如果未捕获异常,则在 process 方法的末尾)。对于状态词,您甚至可能想要指定状态词可以出现的顺序

运行时异常通常不是方法签名的一部分,因此——同样是普遍共识——你应该在方法签名中使用throws声明它们。已检查的异常当然 放在方法签名中。

基本上所有Java卡异常(UserException除外)都是运行时异常,所以关于检查异常的部分可以安全地忽略。有关如何描述异常的一个很好的例子,请查看 Java Card API.