Java 什么时候应该抛出IllegalArgumentException?

Java 什么时候应该抛出IllegalArgumentException?,java,exception,illegalargumentexception,Java,Exception,Illegalargumentexception,我担心这是一个运行时异常,因此应该谨慎使用。 标准用例: void setPercentage(int pct) { if( pct < 0 || pct > 100) { throw new IllegalArgumentException("bad percent"); } } 使其恢复为已检查的异常 好吧,但我们还是继续吧。如果输入错误,则会出现运行时错误。因此,首先,这实际上是一个很难统一实施的政策,因为您可能需要进行相反的转换: pub

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

void setPercentage(int pct) {
    if( pct < 0 || pct > 100) {
         throw new IllegalArgumentException("bad percent");
     }
}
使其恢复为已检查的异常

好吧,但我们还是继续吧。如果输入错误,则会出现运行时错误。因此,首先,这实际上是一个很难统一实施的政策,因为您可能需要进行相反的转换:

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

更糟糕的是,虽然检查
0时“谨慎地”抛出运行时异常并不是一个好策略,但有效的Java建议在调用方可以合理地恢复时使用检查过的异常。(程序员错误是一个具体的例子:如果某个特定案例表明程序员错误,那么您应该抛出一个未经检查的异常;您希望程序员拥有逻辑问题发生位置的堆栈跟踪,而不是自己尝试处理它。)

如果没有恢复的希望,那么可以随意使用未经检查的异常;抓住他们没有意义,所以这很好


但是,从您的示例来看,这个示例在您的代码中出现的情况并不是100%清楚。

谨慎地抛出运行时异常并不是一个好策略——有效的Java建议您在可以合理预期调用方恢复时使用检查过的异常。(程序员错误是一个具体的例子:如果某个特定案例表明程序员错误,那么您应该抛出一个未经检查的异常;您希望程序员拥有逻辑问题发生位置的堆栈跟踪,而不是自己尝试处理它。)

如果没有恢复的希望,那么可以随意使用未经检查的异常;抓住他们没有意义,所以这很好


但是,从您的示例来看,这个示例在您的代码中出现的情况并不是100%清楚。

正如oracle官方教程中指定的,它声明:

如果可以合理预期客户从异常中恢复, 将其设置为选中的异常。如果客户端无法执行任何恢复操作 从异常中,将其设置为未检查的异常。

如果我有一个使用
JDBC
与数据库交互的应用程序,并且我有一个将参数作为
int项和
双倍价格的方法。从数据库表中读取相应项目的
价格
。我只需将购买的
商品的总数乘以
价格
值,然后返回结果。虽然我始终确信在我的终端(应用程序端),表中的价格字段值永远不会为负。但是如果价格值为负怎么办?这表明数据库方面存在严重问题。可能是运营商输入了错误的价格。这是调用该方法的应用程序的另一部分无法预料并且无法从中恢复的问题。这是数据库中的一个
错误。因此,在这种情况下应该抛出
IllegalArguementException()
,这将说明
价格不能为负

我希望我已经清楚地表达了我的观点。

正如oracle官方教程中指定的,它声明:

如果可以合理预期客户从异常中恢复, 将其设置为选中的异常。如果客户端无法执行任何恢复操作 从异常中,将其设置为未检查的异常。

如果我有一个使用
JDBC
与数据库交互的应用程序,并且我有一个将参数作为
int项和
双倍价格的方法。从数据库表中读取相应项目的
价格
。我只需将购买的
商品的总数乘以
价格
值,然后返回结果。虽然我始终确信在我的终端(应用程序端),表中的价格字段值永远不会为负。但是如果价格值为负怎么办?这表明数据库方面存在严重问题。可能是运营商输入了错误的价格。这是调用该方法的应用程序的另一部分无法预料并且无法从中恢复的问题。这是数据库中的一个
错误。因此,在这种情况下应该抛出
IllegalArguementException()
,这将说明
价格不能为负

我希望我已经清楚地表达了我的观点。
IllegalArgumentException的API文档

抛出以指示已向方法传递非法或不适当的参数

从这个角度来看,我会说:

  • 这似乎是一种防御性措施,在输入进入工作并导致某些东西中途出现错误消息之前,抱怨明显的错误输入

  • 它用于抛出检查过的异常(尽管它出现在java.lang.reflect代码中,但在其他情况下,对检查过的异常抛出的荒谬级别的担忧并不明显)太烦人的情况


我将使用
IllegalArgumentException
对常用实用程序进行最后的防御性参数检查(试图与JDK的使用保持一致)。或者期望坏参数是程序员错误,类似于
NullPointerException
。我不会用它在业务代码中实现验证。我当然不会将其用于电子邮件示例。

IllegalArgumentException的API文档

抛出以指示已向方法传递非法或不适当的参数

从这个角度来看,我会说:

  • 这似乎是一种防御性措施,在输入进入工作并导致某些东西中途出现错误消息之前,抱怨明显的错误输入

  • 它被用于一些情况下,它会太
    public void scanEmail(String emailStr, InputStream mime) {
        try {
            EmailAddress parsedAddress = EmailUtil.parse(emailStr);
        }
        catch(ParseException exc){
            throw new IllegalArgumentException("bad email", exc);
        }
    }
    
    void setPercentage(int pct, AnObject object) {
        if( pct < 0 || pct > 100) {
            throw new IllegalArgumentException("pct has an invalid value");
        }
        if (object == null) {
            throw new IllegalArgumentException("object is null");
        }
    }
    
    void setPercentage(int pct) {
        if( pct < 0 || pct > 100) {
             throw new IllegalArgumentException("bad percent");
         }
    }
    
    import com.someoneelse.EmailUtil;
    
    public void scanEmail(String emailStr, InputStream mime) throws ParseException {
        EmailAddress parsedAddress = EmailUtil.parseAddress(emailStr);
    }
    
    /** @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");
      }
    }