6

我想知道在我需要从中选择第一项的列表上进行前置条件检查的最佳模式是什么。

换句话说,我认为列表不应该是null,它的大小应该> 1。

我发现 Guava 的 checkPositionIndex 在这方面没有帮助。相反,我发现它违反直觉,请参阅下面的示例,因为我使用 checkPositionIndex 而不是 checkArgument,如未触发的守卫之后所述,该示例在空列表上进行了轰炸。

即使我从中获取 .get(0) ,检查位置 0 似乎也不足以验证参数?

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkPositionIndex;
import java.util.List;
import com.google.common.collect.Lists;
public class HowShouldIUseCheckPositionIndex {
  private static class ThingAMajig {
    private String description;
    private ThingAMajig(String description) {
      this.description = description;
    }
    @Override
    public String toString() {
      return description;
    }
  }
  private static void goByFirstItemOfTheseAMajigs(List<ThingAMajig> things) {
    checkNotNull(things);
    // Check whether getting the first item is fine
    checkPositionIndex(0, things.size()); // Looks intuitive but...
    System.out.println(things.get(0)); // Finally, help the economy!
    checkArgument(things.size() > 0); // This would have worked :(
  }
  public static void main(String[] args) {
    List<ThingAMajig> fullList =
        Lists.newArrayList(new ThingAMajig(
            "that thingy for the furnace I have been holding off buying"));
    List<ThingAMajig> emptyList = Lists.newLinkedList();
    goByFirstItemOfTheseAMajigs(fullList);
    // goByFirstItemOfTheseAMajigs(emptyList); // This *bombs*
  }
}
4

5 回答 5

16

你应该checkElementIndex()改用。

checkPositionIndex()确保给定位置是插入新元素的有效位置(即您可以add(0, obj)在空列表上执行),而不是从中获取元素的有效索引。

于 2012-09-18T11:00:44.433 回答
3

事实上,您根本不需要进行检查。

list.get(0)调用本身已经抛出基本完全相同的错误消息。

但是,如果您确实想明确地进行检查,是的,使用checkElementIndexor checkArgument(!list.isEmpty())

于 2012-09-18T21:59:46.160 回答
0

使用checkElementIndex

它指出:

Ensures that index specifies a valid element in an array, list or string of size size. An element index may range from zero, inclusive, to size, exclusive

于 2012-09-18T11:03:26.367 回答
0

您可以使用checkNotBlank方法的twitter-commons实现。它验证 Iterable 不为 null 且不为空。这是实现:

/**
* Checks that an Iterable is both non-null and non-empty. This method does not check individual
* elements in the Iterable, it just checks that the Iterable has at least one element.
*
* @param argument the argument to validate
* @param message the message template for validation exception messages where %s serves as the
* sole argument placeholder
* @param args any arguments needed by the message template
* @return the argument if it is valid
* @throws NullPointerException if the argument is null
* @throws IllegalArgumentException if the argument has no iterable elements
*/
public static <S, T extends Iterable<S>> T checkNotBlank(T argument, String message,
      Object... args) {
  Preconditions.checkNotNull(argument, message, args);
  Preconditions.checkArgument(!Iterables.isEmpty(argument), message, args);
  return argument;
}

非常简单,适用于所有可迭代对象。

于 2012-09-18T11:10:17.220 回答
0

您可以将 valid4j 与 hamcrest-matchers 一起使用(在 Maven Central 上以 org.valid4j:valid4j 的形式找到)

对于前置条件和后置条件(基本上是断言 -> 抛出 AssertionError):

import static org.valid4j.Assertive.*;

require(list, hasSize(greaterThan(0)));

或用于输入验证(抛出您的自定义可恢复异常):

import static org.valid4j.Validation.*;

validate(list, hasSize(greaterThan(0)), otherwiseThrowing(EmptyListException.class));

链接:

于 2014-11-30T23:55:08.010 回答