Why doesn't Google Guava Preconditions checkArgument return a value?

I really like how the guava library allows simple single-line installations to check for null:

public void methodWithNullCheck(String couldBeNull) { String definitelyNotNull = checkNotNull(couldBeNull); //... } 

Unfortunately, for a simple argument check, you need at least two lines of code:

 public void methodWithArgCheck(String couldBeEmpty) { checkArgument(!couldBeEmpty.isEmpty()); String definitelyNotEmpty = couldBeEmpty; //... } 

however, you can add a method that could check the argument and return a value if the test was successful. The following is an example of verification and how to implement it:

 public void methodWithEnhancedArgCheck(String couldBeEmpty) { String definitelyNotEmpty = EnhancedPreconditions.checkArgument(couldBeEmpty, !couldBeEmpty.isEmpty()); //... } static class EnhancedPreconditions { public static <T> T checkArgument(T reference, boolean expression) { if (!expression) { throw new IllegalArgumentException(); } return reference; } } 

I just wondered what the design is and if it is worth putting a function request for this.

EDIT : @ Nice, yes, method checks can be awkward. However, the checks in the constructors for zeros look really good and save a lot of time debugging NPEs:

 public class SomeClassWithDependency { private final SomeDependency someDependency; public SomeClassWithDependency(SomeDependency someDependency) { this.someDependency = checkNotNull(someDependency); } //... 

EDIT . I accept the answer to Nizet because I agree with him on the side effects and consistency. Also, if you look at the Xaerxess comment, this seems to be perplexing among other developers.

+6
source share
3 answers

I never understood why checkNotNull() returns its argument in the first place:

 public void foo(String bar) { Preconditions.checkNotNull(bar); // here, you're sure that bar is not null. // No need to use another variable or to reassign bar to the result // of checkNotNull() } 

I personally ignore the result of checkNotNull() as above. And that makes things compatible with other checks that return void.

The only advantage I see is that you can do something similar, but I find it less readable than doing it on two separate lines:

 public String trim(String bar) { return Preconditions.checkNotNull(bar).trim(); } 

So, in short, I agree with you that the API is somewhat inconsistent, but I would prefer that all methods return void. The method should either have a side effect or return something, but in both cases both should be avoided. The purpose of the method here is to have a side effect: throwing an exception.

EDIT:

Your example is indeed a more informed explanation of why returning an argument is useful. But I would prefer consistency and cleanliness instead of this ability to check and assign on a single line.

+2
source

The biggest reason checkNotNull returns its argument, so it can be used in constructors, for example:

 public Foo(Bar bar) { this.bar = checkNotNull(bar); } 

But the main reason that checkArgument doesn't do something like this is because you have to pass the argument separately anyway, and it just doesn't look like this - especially with more complex prerequisite checks, which can sometimes be more readable on their own line. Just because something can be single-line doesnโ€™t mean what it should be if it doesnโ€™t increase readability.

+22
source

Instead, you can use valid4j with hamcrest-matchers (found on Maven Central as org.valid4j: valid4j)

For preconditions and postconditions:

 import static org.valid4j.Assertive.*; this.myField = require(argument, notNullValue()); this.myInteger = require(x, greaterThan(0)); ... return ensure(result, isValid()); 

To confirm the entry:

 import static org.valid4j.Validation.*; validate(argument, isValid(), otherwiseThrowing(InvalidException.class)); 

References:

+1
source

Source: https://habr.com/ru/post/921600/


All Articles