Is there an beautiful way to assert pre-conditions in Java methods?

心不动则不痛 提交于 2019-11-30 12:17:40

Guava's Preconditions class is just for this. You typically use it with static imports, so your example would look like:

checkArgument(start < end, "Start must be before end");

It makes it easy to add more information to the message as well, without paying the cost of String concatenation if the check passes.

checkArgument(start < end, "Start (%s) must be before end (%s)", start, end);

Unlike assert statements, these can't be disabled.

Check out the Cofoja project which provides contracts for Java through annotations. It provides Pre-/Postconditions and Invariants. Also in contrast to other Java implementations it correctly handles contracts defined in parent classes/interfaces. Contract evaluation can be enabled/disabled at runtime.

Here is a code snippet from their tutorial:

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);
}

How about assert start < end. Have a look at the documentation.

Aspect oriented programming can be used for such a problem. Method calls can be intercepted checking for the invariant. Pointcuts and advices are configured in a declarative way. Spring and Guice make usage of AOP straightforward.

Here's an example in Guice.

You might be able to do this with annotation and aspect orientated programming.

I would use IllegalArgumentException if an argument combination is not legal. I would use IllegalStateException is in a state which prevents the method from working.

You can create a helper method for the exception.

public static void check(boolean test, String message) {
    if(!test) throw new IllegalArgumentException(message);
}

check(start < end, "Start must be before end.");
avandeursen

For input validation, you can also use Apache Commons Validator.

Note that input validation should always be enabled. Hence it is conceptually very different from assertion checking (as, e.g., in Eiffel), which can be optionally on/off -- see the answer to this related stack overflow question When should I use Apache Commons' Validate.isTrue, and when should I just use the 'assert' keyword?

If I find myself repeating the same boiler-plate precondition checking code within a class, I refactor my code to reduce the duplication and to increase abstraction by extractung the repeated code into a new (static private) method. I use the Java-7 Objects.requireNonNull method for null checks.

The JUnit package has constructs like assert that would aid in doing such condition check.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!