1

Objects contains 2 method overloads where one takes an object and the other takes a Supplier of that object:

public static <T> T requireNonNull​(T obj, String message)
public static <T> T requireNonNull​(T obj, Supplier<String> messageSupplier)

and the similar

public static <T> T requireNonNullElse​(T obj, T defaultObj)
public static <T> T requireNonNullElseGet​(T obj, Supplier<? extends T> supplier)

The methods that take a supplier have the advantage of deferring the evaluation of the second argument, but the disadvantage of creating a Supplier instance. This is noted in the docs for requireNonNull​(T obj, Supplier<String> messageSupplier):

Unlike the method requireNonNull(Object, String), this method allows creation of the message to be deferred until after the null check is made. While this may confer a performance advantage in the non-null case, when deciding to call this method care should be taken that the costs of creating the message supplier are less than the cost of just creating the string message directly.

While the real answer would always be to perform benchmarks, it's counterproductive to do so for every case and most of the times this is not the bottleneck. However, we do come across these situations often enough and since we're given the choice, we rather make the correct one, in which case "eyeballing" can be very helpful.

Except for cases when the second argument is already evaluated (for which this question makes little sense), when would creating the second argument be more expensive than a supplier? There must be some guidelines as to when the correct choice is obvious enough.

I remind that Strings are a special case because of their pool.

  • 2
    v = requireNonNull(largeDictionary.get(parameter), parameter + "is unavailable. Existing parameters are "+ largeDictinary) – Basilevs Aug 28 '18 at 19:03
  • @Basilevs What am I supposed to do with that? – user1803551 Aug 28 '18 at 19:41
  • 2
    I think @Basilevs was trying to provide an example of when you would benefit from using a Supplier<T> object? – Greg Burghardt Aug 28 '18 at 19:47
2

You've already answered your question:

While the real answer would always be to perform benchmarks, it's counterproductive to do so for every case and most of the times this is not the bottleneck.

The real answer is run benchmarks first after noticing a performance problem, or in use cases where you have run into noticeable performance problems in the past. Only after running the bench mark and discovering there is a problem do you need this additional layer of abstraction.

Then again it is cheap in terms of CPU and RAM to just create the Supplier object to begin with.

Oddly enough, it seems the decision to use Supplier to begin with, or only after running benchmarks is the "Premature Optimization."

Even if you do not measure a need to use Supplier and the lazy loading it enables, it is cheap in terms of performance to use it, so make a judgement call up front. Use it or don't, but don't waste a lot of time trying to decide.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.