是否有一种美妙的方式来断言Java方法中的前提条件?

Sal*_*ley 11 java eiffel contract

我的很多函数在声明之下都有一大堆验证代码:

if ( ! (start < end) ) {
    throw new IllegalStateException( "Start must be before end." );
    }
Run Code Online (Sandbox Code Playgroud)

我想精确地指定某些输入的有效范围 - 例如A> B,C => 1或str_d.length()> 0.

鉴于我的一些函数有很多必须经过验证的论证,我最终可能会编写大量的样板来验证前置条件.我正在编写一个主要由非技术开发人员使用的库,我们发现验证函数输入是帮助我们的用户正确操作API的最佳方法.我们越早提出错误,客户就越不需要做的工作.

是否有更优雅的方法来指定我的方法中的前置条件,后置条件(以及可能的不变条件).

一位同事告诉我有关Eiffel编程语言的一个特性,它允许以非常自然的方式描述前/后/不变条件,而无需重复大量的样板代码.是否有Java语言的附加组件,这将允许我使用这些魔术?

Col*_*inD 12

番石榴前提条件就是为了这个.您通常将它与静态导入一起使用,因此您的示例如下所示:

checkArgument(start < end, "Start must be before end");
Run Code Online (Sandbox Code Playgroud)

它还可以轻松地向消息添加更多信息,而无需支付String经过检查的连接成本.

checkArgument(start < end, "Start (%s) must be before end (%s)", start, end);
Run Code Online (Sandbox Code Playgroud)

assert语句不同,这些不能被禁用.


Arn*_*iva 6

查看Cofoja项目,该项目通过注释提供Java合同.它提供前/后条件和不变量.与其他Java实现相比,它正确处理父类/接口中定义的契约.可以在运行时启用/禁用合同评估.

这是他们教程中的代码片段:

import com.google.java.contract.Invariant;
import com.google.java.contract.Requires;

@Invariant("size() >= 0")
interface Stack<T> {
  public int size();

  @Requires("size() >= 1")
  public T pop();

  public void push(T obj);
}
Run Code Online (Sandbox Code Playgroud)


nfe*_*ner 5

如何assert start < end.看看文档.


Bor*_*vić 5

面向方面的编程可以用于这样的问题.可以拦截方法调用以检查不变量.切入点和建议以声明方式配置.SpringGuice直截了当地使用AOP.

这是Guice的一个例子.