Guava preconditions checkNull, checkArgument

I want to check preconditions on a base class so that I know subtypes will always use constructor arguments that are valid.

Let's take as an example a constructor that:

  • takes 2 or more parameters
  • takes parameters of different types
  • for one parameter, it performs multiple checks (eg String is not null and not empty)
  • How would one best use the Guava preconditions approach in that case?

    In a mock example like this: (this is contrived!)

    protected AbstractException(String errorMessage, Throwable errorCause) {
      super(errorMessage, errorCause);
      checkNotNull(errorMessage,
          ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK, "errorMessage");
      checkArgument(!errorMessage.isEmpty(),
          ErrorMessage.MethodArgument.CANNOT_BE_EMPTY_STRING_CHECK,
          "errorMessage");
      checkNotNull(errorCause, ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK,
          "errorCause");
    }
    

    I end up calling super before checking the arguments because a call to super needs to be the first line of the method and, although I could do super(checkNoNull(errorMessage)) , I cannot do the same wrapping using checkArgument because that returns void . So the dilemma is:

  • Where do I put the checks on all arguments? I don't want to create a Builder just for that
  • How do I "group" checks as in a fictitious checkStringNotNullAndNotEmpty()
  • Should I rather think about integration with matchers frameworks? (hamcrest, fest assertions...)
  • I use the odd-looking ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK because the default throw does not include an error message so from the testing side I cannot recognise this as an argument validation failure rather than a "any" NPE?

    Am I doing it all wrong?


    This should have been a comment, but it's too long.

  • Calling super before the test is harmless provided that the super ctor doesn't do things which it shouldn't do anyway.
  • It could be prevented via a static builder method, you need no Builder. But it's not worth it.
  • I doubt that grouping tests is generally useful; if it was, then there would be a such method already. But if you need one such a concrete thing more than twice, then write your own; if it comes often, report it to the Guava team as an RFE.
  • I'm pretty sure, matchers are an overkill here as you're just creating an exception, ie, something used only rarely (I hope). As your test is runtime only, it can't really help to catch errors. It would be nice, if you could statically ensure a "properly" constructed exception, but it's impossible in pure java.
  • More important: The exceptions you're throwing are probably inferior to the ones you'd get without all the checks. Imagine the user provides a cause and no message. That's bad, you think, but you replace it with an NPE lacking any cause. That's worse.

    Look at Guava's Preconditions.format (package private). They could check the correct number of arguments first, but they do not. You can provide too few or too many, which is an error, but ignoring it is the best way to handle it.

    链接地址: http://www.djcxy.com/p/76230.html

    上一篇: 服务层:如果查询参数为null,返回什么?

    下一篇: 番石榴前提条件checkNull,checkArgument