Java 禁止空字符串参数和抛出RuntimeException以阻止方法继续的利弊

Java 禁止空字符串参数和抛出RuntimeException以阻止方法继续的利弊,java,spring,illegalargumentexception,string,Java,Spring,Illegalargumentexception,String,假设我在Spring服务层中有以下方法定义: @Override public boolean passwordsMatch(String encrypted, String plain) { if (encrypted == null || encrypted.isEmpty() || plain == null || plain.isEmpty()) { throw new IllegalArgumentException("One argument is

假设我在Spring服务层中有以下方法定义:

@Override
public boolean passwordsMatch(String encrypted, String plain) {
      if (encrypted == null || encrypted.isEmpty() || plain == null || plain.isEmpty()) {
            throw new IllegalArgumentException("One argument is null or empty");
        }
      return passwordEncoder.matches(plain, encrypted);
   }
它由Spring MVC应用程序控制器调用,希望检查用户提供的新密码(此处称为“普通”)是否与用户的当前密码(此处称为“加密”)匹配

如果用户提供的新密码为空(
plain.isEmpty()
),我真的应该抛出IllegalArgumentException(或RuntimeException的任何子类型)


我有95%的把握我会删除这张支票,但我很想听到在这种特殊情况下支持保留支票的论点。

我写得太快了。该方法似乎是一种用于比较密码的服务方法。这个领域无关紧要。在这种特定的情况下,如果提供的参数是
null
,则抛出
IllegalArgumentException
是有意义的,但对于空字符串则没有意义,因为它实际上可能是密码



在涉及域验证的用例中,我不会使用
IllegalArgumentException
。如果您的
用户
实例(或其他任何实例)的密码为空,则该实例将不会处于有效状态。因此,您应该抛出某种类型的
InvalidDomainException
,例如
InvalidPasswordException
(或者使用带有
验证器的
BindingResult
)。

应该是您在方法中得到不喜欢的参数时的第一选择(这正是这个异常的目的)。因此,除非您已经(或觉得有必要实现)了一个更具体/有意义的异常,否则为了保持一致性,我认为使用IllegalArgument/IllegalState是可以的

但是,在异常消息中指出您不喜欢的特定参数可能是一个好主意。顺便说一句,Guava通过其实用程序为此类验证提供了非常好的支持


现在您已经澄清了实际的问题范围,我想说,在弄清楚这个方法到底应该检查什么之后,您是唯一一个决定如果提供了null或空参数,您的方法是否应该继续的人


基于您方法的名称,我认为它最多应该不允许
null
值,因为空密码仍然可以与其加密表示形式匹配。“最小密码长度”规则最有可能在其他地方实现;此方法应该只报告普通密码是否与哈希匹配,而不管它是否是合法密码。

根据您的解释,很难找出抛出IAE的合适用例。您认为使用它是一种糟糕的做法吗?@CostiCiudatu In作为一种服务层方法,IMO,抛出一个IAE是有意义的。如果您另外将其写入API(例如javadoc),它会更好。我想说的是,对于一个正确定义的“域”,任何验证都是“域验证”,但您同时澄清了自己的观点。作为补充说明,在方法签名中声明抛出的异常(甚至是运行时异常)可能是最好的文档。关于“因为它实际上可能是密码”的观点很好。实际上,应用程序中不允许使用空字符串作为密码。但其他地方也检查了此约束。@balteo Good。这正是我试图说明的要点。在Spring应用程序中,您可能会使用带有
BindingResult
@Valid
验证器来验证您的模型。此外,Java 7还有
对象。requirennull(arg,String)
用于
null
检查。我没有为我的帖子选择完全合适的标题:我的意思是“如果提供了空字符串参数,则不允许并引发任何运行时异常的利弊”。现在编辑我的标题。@balteo:那么你开始了一场完整的
IllegalArgumentException
战争只是为了好玩??开玩笑:)@balteo总是尝试抛出最可接受的特定
异常。
Preconditions.checkArgument(encrypted != null && !encrypted.isEmpty(), "The old password hash is empty");
Preconditions.checkArgument(plain != null && !plain.isEmpty(), "The new password is empty");