2

Probably asked before, but could not find it.

I am writing a lot of statements in the form:

if (bar.getFoo() != null) {
    this.foo = bar.getFoo();
}

I thought of the ternary operator, but that doesn't make it much better in my opinion:

this.foo = bar.getFoo() != null ? bar.getFoo() : this.foo;

My main problem is that I have to write bar.getFoo() twice in both situations. Of course I can write a helper method that solves this, but I was wondering if there were more elegant solutions.

Different from: Avoiding != null statements because that question does not deal with assigning to a value the value that is null checked on.

Martijn Burger
  • 7,315
  • 8
  • 54
  • 94

5 Answers5

6

This avoids the if statement and calls getFoo() once. But you have to type this.foo twice:

this.foo = Objects.requireNonNullElse​(bar.getFoo(), this.foo);

requireNonNullElse​ docs

Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
3

Using a helper method is not a bad idea. For example that's what the Map interface does with its geetOrDefault method - in your case it would look like:

//in Bar
public Foo getFooOrDefault(Foo defaultValue) {
  return foo == null ? defaultValue : foo;
}

Alternatively, you could enforce foo != null if that's compatible with your use case and get rid of the null check altogether.

Finally you could also return an Optional<Foo>:

//in Bar
public Optional<Foo> getFoo() {
  return Optional.ofNullable(foo);
}

//in your code:
bar.getFoo().ifPresent(f -> this.foo = f);
assylias
  • 321,522
  • 82
  • 660
  • 783
  • I would discourage the return of an `Optional` since, in theory, one would have to check whether the `Optional` itself is `null`. – Turing85 Jan 12 '18 at 11:48
  • 1
    @Turing85 Returning a null Optional would be very bad design. In my example, the Optional is never null - it may be empty. So there is no need or reason to check for null as you suggest. – assylias Jan 12 '18 at 11:50
  • Then you may want to declare the method `getFooOrDefault(...)` as `final` =) – Turing85 Jan 12 '18 at 11:51
  • Also, you do not check whether parameter `defaultValue` is `null`. – Turing85 Jan 12 '18 at 11:58
  • @Turing85 Using final why not, or add some javadoc that clearly states the contract of the method. As for checking defaultValue for null, I don't see the point - if the caller wants null that's what she gets. – assylias Jan 12 '18 at 12:00
3

As written in Optional javadoc:

A container object which may or may not contain a non-null value.

Having said that this is the most "java-8" way of dealing with null checks. This was one of the original intentions of Java Optional introduction. Having getFoo returning an Optional you can just use the ifPresent function on the Optional and you are good to go.

1

I'd do a

Foo tmpFoo = bar.getFoo();
if (tmpFoo != null)
    this.foo = tmpFoo;

That eliminates the superfluous function call.

Ronald
  • 2,842
  • 16
  • 16
0

Other answers already point out the right solution (from java-8+), which is the Optional<T> class.


I just wanted to add that there was a proposal back in 2009, which recalls nowadays' Kotlin's safe-calls (what many Java programmers, including me, badly desire)

Quoting from the proposal link:

we can compute the name of a member if the group is non-null and non-empty and the first member has a known (non-null) name, otherwise the string "nobody":

final String aMember = g?.members?[0]?.name ?: "nobody";

Without this feature, a developer would currently write:

String aMember = null;
if (g != null && g.members != null && g.members[0].name != null) {
    aMember = g.members[0].name;
} else {
    aMember = "nobody";
}

The proposed version is a lot shorter, clearer, and can even be assigneed to a final variable.

No idea what happened to it, but it would have saved us many lines of code.

payloc91
  • 3,724
  • 1
  • 17
  • 45