1

This is a code segment from another StackOverflow question:

@Override
public String convertToDatabaseColumn(final UUID entityValue) {
    return ofNullable(entityValue).map(entityUuid -> entityUuid.toString()).orElse(null);
}

I am really struggling to understand the use of the Optional class. Is the return code saying "return the value of the map (a String) or NULL if that fails?

How can return be acting on a method rather than a Class - that is Optional.ofNullable()?

GhostCat
  • 137,827
  • 25
  • 176
  • 248
skyman
  • 2,255
  • 4
  • 32
  • 55
  • "_How can return be acting on a method rather than a Class_" - `return` doesn't act on "methods" or "classes" - it acts on **expressions**. `return getStuff()` is perfectly valid if `getStuff()` itself returns an approriate value. `return calculateStuff(10).toString()` is perfectly valid if the method returns a `String`. – Boris the Spider Jun 25 '18 at 06:50
  • 2
    Don't use `Optional` like that, I know the (maybe only) situation suitable for `Optional` is as the return value of a method to indicate the client to handle the null – a.l. Jun 25 '18 at 06:54
  • I appreciate the quick accept! – GhostCat Jun 25 '18 at 08:12

5 Answers5

8

This is a really bad use of Optional. In fact the java developers themself say that optional should not be used in such cases, but only as a return argument from a method. More can be read in this great answer: Is it good practice to use optional as an attribute in a class

The code can be rewritten to this:

@Override
public String convertToDatabaseColumn(final UUID entityValue) {
    return entityValue == null ? null : entityValue.toString();
}
Lino
  • 19,604
  • 6
  • 47
  • 65
3

Is the return code saying "return the value of the map (a String) or NULL if that fails?

Yes. You can check the documentation of Optional here. It tells you exactly what map and orElse do.

How can return be acting on a method rather than a Class - that is Optional.ofNullable()?

You are not returning the method. You are returning the return value of a method. Look at this simple example:

int myMethod() {
    return foo();
}

int foo() { return 10; }

See? I am not returning foo the method, I am returning 10, the return value of foo.

Note that it is possible to return methods, with functional interfaces.

In this case, you are returning the return value of the last method in the method chain, orElse. ofNullable creates an Optional<T>, then map is called on this object and returns a new Optional<T>, then orElse is called and its return value is returned.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • `Note that it is possible to return methods, with functional interfaces` -> not really, no. Only in the syntax sense - what is returned is not a "method". – Boris the Spider Jun 25 '18 at 06:53
  • @BoristheSpider That's what I mean, yes. I just want to make it as easy as possible for what seems like a beginner to understand. – Sweeper Jun 25 '18 at 06:55
2

Lets go step by step:

ofNullable(entityValue)

creates an Optional of the incoming parameter (which is allowed to be null, using of() a NPE gets thrown for null input)

.map(entityUuid -> entityUuid.toString())

Then you pick the actual value, and invoke toString() on that value ... which only happens if entityValue isn't null. If it is null, the result comes from orElse(null).

In the end, the result of that operation on the Optional is returned as result of the method.

The above code is nothing but a glorified version of

if (entityValue == null) return null;
return entityValue.toString();

Optionals have their place in Java, but your example isn't a good one.

It doesn't help readability a bit, and you are not alone with wondering "what is going on here".

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • I would add another point for the Russian Blue - if I could :) maybe British shorthair - hard to tell – skyman Jun 25 '18 at 07:21
1

The code can be turn like this :

public String convertToDatabaseColumn(final UUID entityValue) {
    if(entityValue==null){
        return null;
    }else{
        return entityValue.toString();
    }
}

Your initial code have two statements: Optional.ofNullable(entityValue): create an Optional Object to say the value can be present or not. .map(entityUuid -> entityUuid.toString()).orElse(null); you apply some operation to your Optional object, return a string of it or null.

This will avoid a null pointer exception in a more elegant way.

EFOE
  • 609
  • 1
  • 10
  • 20
0

Optional.ofNullable(T value):

Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.

Optional.orElse(null)

Return the value if present, otherwise return null.

Follow this link

chand mohd
  • 2,363
  • 1
  • 14
  • 27