【问题标题】:Is there a good field validation available in java 8+ which could replace guava PreConditions?java 8+ 中是否有一个很好的字段验证可以替代 guava PreConditions?
【发布时间】:2019-03-24 12:57:34
【问题描述】:

我想在我的应用程序的方法中添加字段验证(例如,字段不为空且为正)。

private void assertionTest(Integer i) {
    // want to first assert here that i is not null and positive 
    // something like: 
    // Preconditions.checkArgument( i != null && i > 0, "i should be non null positive number!" );
    // 
    System.out.println( "i: " + i);
}

Java 8 引入了 Objects 类,该类具有一些用于 null 检查验证的基本实用方法:

public static <T> T requireNonNull(T obj)
public static <T> T requireNonNull(T obj, String message)

但它仍然缺乏 guava 的 Preconditions 类提供的完整验证列表,如下所示:

checkArgument(boolean) throws IllegalArgumentException
checkState(boolean) throws IllegalStateException
etc.

在 Java 8+ 中是否有更好的替代方法来进行字段验证,这样我就不必为此包含像 guava 这样的外部库?

【问题讨论】:

  • 请注意:Guava 几乎是 3MB 的压缩字节码。不要为了省去写这几个单行方法而包含 Guava
  • 您的问题的答案是:不,没有。
  • 它没有,但考虑到番石榴还有多少其他好东西......
  • 从 Java 9 开始,还有Objects.checkIndex(…) 方法家族。但不会有“详尽的验证清单”。由于可能的条件数不胜数,因此即使试图涵盖所有这些条件也是没有意义的。
  • @saurabh.in 你的问题解决了吗?

标签: java validation java-8


【解决方案1】:

Java 8+(直到 12)没有这种方法(也许将来会出现一些变化)。

  • 从纯Java端,你可以使用assert

     assert <condition> : <message>
    

如果断言失败,AssertionError 将与 &lt;message&gt; 一起抛出。

但是,您应该确保通过将-ea 属性添加到JVM 来激活它。
断言为失败的案例添加了更多有意义的信息。
但是,断言的目的不是检查方法参数。因此,看看第二种方法。

  • 作为替代方案,您可以使用apache-commons-lang Validate 类:

     Validate.notNull(i, "this parameter can't be null")
     Validate.isTrue(i > 0, "The value must be greater than zero: %d", i);
    

这种方法更适合验证方法的参数。


如果您使用的是 Spring 框架,则可以使用 Assert 类。

Snipept From documentattion - 有助于验证参数的断言实用程序类。

用法如下:

Assert.notNull(clazz, "The class must not be null");
Assert.isTrue(i > 0, "The value must be greater than zero");

【讨论】:

  • 感谢 nazar_art。 Java assert 关键字适合我的用例。在我的测试中,当断言失败时,它会抛出 AssertionError 和我的自定义消息。
  • @nazar_art 请记住,当然有人可以禁用断言
  • assert 应该用于检查不变量,不是传入的参数值。
【解决方案2】:

我想您可以为此使用Apache Commons Lang。他们在Validate class 中有很多验证方法。我不确定它是否足够有表现力,但是如果您需要其他任何内容,可以自己编写它,不应该有太多用于简单检查的代码。

此外,如果您想将这些检查集成到您的主要业务逻辑代码中(不仅仅是单元测试),您应该查看Bean Validation。这样,您绝对不会重新发明轮子,您的测试只需要期待验证框架的异常。

干杯。

【讨论】:

    【解决方案3】:

    我使用弹簧验证,但有时我通过扩展弹簧验证来编写验证以控制一些自定义行为

    【讨论】:

      【解决方案4】:

      如果您更喜欢验证方法,为什么不自己编写呢?很多人都这样做。它简单、快速且不需要任何外部依赖。

      请记住,这些方法中的大多数只是简单的 if 条件名称!

      然后是 JSR 380 a.k.a “Bean Validation”。它允许您使用注释定义验证约束:

      void assertionTest (@NotNull @PositiveOrZero Integer i) { ... }
      

      BV 对大型应用程序有几个好处:

      • 更简洁,您可以在一个地方定义约束
      • 许多有用的预定义约束
      • 自定义注释
      • 本地化错误消息(可轻松自定义)
      • 考虑性能的复杂对象和对象图的验证
      • 上下文感知验证
      • 与其他库和框架集成
      • 等等

      看看reference implementationn's documentation

      【讨论】:

        【解决方案5】:

        IMO 最好的解决方案就是使用

        if (! test) { throws new Illegal[Argument|State]Exception (message + badparameteror) }
        

        即使是 Guava 的作者也对使用他们的验证方法有不同的感受,尤其是在性能受到关注的情况下。

        如果你发现自己为某个特定的类做了很多这样的事情,你可以只创建一个辅助方法,但我强烈建议你不要为了琐碎的验证而需要整个库。

        【讨论】:

          【解决方案6】:

          有时我使用java.util.Optional 来验证自定义ExceptionRuntimeException

          Optional.ofNullable(someVariables)
                    .orElseThrow(
                        () ->
                            new CustomException("Some message"));
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-04-28
            • 2020-12-10
            • 1970-01-01
            • 1970-01-01
            • 2011-08-02
            • 2017-11-11
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多