当前位置: 首页 > 面试题库 >

什么时候应该抛出IllegalArgumentException?

南宫星波
2023-03-14
问题内容

我担心这是运行时异常,因此应谨慎使用。
标准用例:

void setPercentage(int pct) {
    if( pct < 0 || pct > 100) {
         throw new IllegalArgumentException("bad percent");
     }
}

但这似乎会强制执行以下设计:

public void computeScore() throws MyPackageException {
      try {
          setPercentage(userInputPercent);
      }
      catch(IllegalArgumentException exc){
           throw new MyPackageException(exc);
      }
 }

使它回到被检查的异常。

好的,但是让我们开始吧。如果输入错误,则会出现运行时错误。首先,这实际上是统一实施的相当困难的策略,因为您可能必须执行相反的转换:

public void scanEmail(String emailStr, InputStream mime) {
    try {
        EmailAddress parsedAddress = EmailUtil.parse(emailStr);
    }
    catch(ParseException exc){
        throw new IllegalArgumentException("bad email", exc);
    }
}

更糟的是-虽然0 <= pct && pct <= 100可以预期客户端代码将以静态方式进行检查,但对于更高级的数据(例如电子邮件地址)却并非如此,或更糟糕的是,必须对数据库进行检查,因此,一般而言,客户端代码无法预先执行-
验证。

因此,基本上,我的意思是我看不到使用有意义的一致政策IllegalArgumentException。似乎不应该使用它,我们应该坚持我们自己的检查异常。有什么好的用例来抛出这个?


问题答案:

将其IllegalArgumentException视为 前提条件 检查,并考虑设计原则:
一种公共方法应同时知道并公开记录其自身的前提条件。

我同意这个例子是正确的:

void setPercentage(int pct) {
    if( pct < 0 || pct > 100) {
         throw new IllegalArgumentException("bad percent");
     }
}

如果EmailUtil是opaque ,这意味着由于某些原因无法将最终条件描述给最终用户,则检查的异常是正确的。第二个版本,为此设计进行了更正:

import com.someoneelse.EmailUtil;

public void scanEmail(String emailStr, InputStream mime) throws ParseException {
    EmailAddress parsedAddress = EmailUtil.parseAddress(emailStr);
}

*例如, *如果EmailUtil是透明的
IllegalArgumentException则它可能是所讨论的类所拥有的私有方法,并且仅当前提条件可以在功能文档中描述时才是正确的。这也是一个正确的版本:

/** @param String email An email with an address in the form abc@xyz.com
 * with no nested comments, periods or other nonsense.
 */
public String scanEmail(String email)
  if (!addressIsProperlyFormatted(email)) {
      throw new IllegalArgumentException("invalid address");
  }
  return parseEmail(emailAddr);
}
private String parseEmail(String emailS) {
  // Assumes email is valid
  boolean parsesJustFine = true;
  // Parse logic
  if (!parsesJustFine) {
    // As a private method it is an internal error if address is improperly
    // formatted. This is an internal error to the class implementation.
    throw new AssertError("Internal error");
  }
}

这种设计可以任意选择。

  • 如果前提条件的描述成本很高,或者如果该类打算由不知道其电子邮件是否有效的客户使用,则请使用ParseException。这里的顶级方法被命名scanEmail,它暗示最终用户打算通过其发送未研究的电子邮件,因此这可能是正确的。
  • 如果前提条件可以在功能文档中描述,并且该类无意输入无效,并因此指示编程器错误,请使用IllegalArgumentException。尽管未“选中”,但“选中”移至记录该功能的Javadoc,希望客户端遵守该功能。 IllegalArgumentException 客户事先不能说出自己的论点是非法的是错误的。

关于IllegalStateException的注释 :这意味着“此对象的内部状态(私有实例变量)无法执行此操作。”
最终用户看不到私有状态,所以松散地说IllegalArgumentException,在客户端调用无法得知对象状态不一致的情况下,它优先于私有状态。尽管它比检查异常更可取,但我没有很好的解释,尽管例如初始化两次或丢失无法恢复的数据库连接之类的例子。



 类似资料:
  • 我担心这是一个运行时异常,所以应该谨慎使用。 标准用例: 但这似乎会迫使以下设计: 将其恢复为检查异常。 好吧,但我们还是继续吧。如果输入错误,则会出现运行时错误。因此,首先,这实际上是一个很难统一实施的政策,因为您可能需要进行相反的转换: 更糟糕的是,在检查

  • 问题内容: 在我的应用程序中,有时会引发以下异常: 很难找到错误,因为在stacktrace中没有列出我的方法。那么,有人知道何时抛出此异常吗?感谢您的任何提示。 问题答案: 您可以在stacktrace中看到错误: 适配器的内容已更改,但ListView没有收到通知。确保不从后台线程修改适配器的内容,而仅从UI线程修改。 您应该调查一个线程,并使其与UI线程同步。 在Android中执行此操作的

  • 我们应该在什么时候选择抛出一个异常? 我们可以在try catch中捕获此异常。 在哪种情况下,我们选择使用投掷而不是立即接球?是否与设计模式相关?

  • 问题内容: 我知道他们两个都禁用了Nagle的算法。 我什么时候应该/不应该使用它们中的每一个? 问题答案: 首先,不是所有人都禁用Nagle的算法。 Nagle的算法用于减少有线中更多的小型网络数据包。该算法是:如果数据小于限制(通常是MSS),请等待直到收到先前发送的数据包的ACK,同时累积用户的数据。然后发送累积的数据。 这将对telnet等应用程序有所帮​​助。但是,在发送流数据时,等待A

  • 问题内容: 在该类中,有两个字符串,和。 有什么不同?我什么时候应该使用另一个? 问题答案: 如果你的意思是和则: 用于在文件路径列表中分隔各个文件路径。考虑在上的环境变量。您使用a分隔文件路径,因此在上将是;。 是或用于拆分到特定文件的路径。例如在上,或

  • 我已经用Java编写代码一段时间了。但有时,我不知道什么时候应该抛出异常,什么时候应该捕获异常。我正在做一个有很多方法的项目。层次结构是这样的- 所以目前我正在做的是-我在所有方法中抛出异常并在方法A中捕获它,然后将其记录为错误。 但我不确定这是否是正确的方法?或者我应该开始在所有方法中捕获异常。这就是为什么这种混乱始于我的 - 我什么时候应该抓住异常与何时应该抛出异常。我知道这是一个愚蠢的问题,