Wolfone Wolfone - 5 months ago 24
Java Question

Java LocalDate: Parse-Implementation with method reference or without, difference, best practice?

i am working with LocalDate the first time right now in my attempt to learn java. The reference would be this tutorial:

JavaFX8 Tutorial-Part3

Specifically this piece of code (with one additional comment-line):

public static LocalDate parse(String dateString) {
try {
return DATE_FORMATTER.parse(dateString, LocalDate::from);
//return LocalDate.parse(dateString, DATE_FORMATTER);
} catch (DateTimeParseException e) {
return null;
}
}


The first return is the same as in the tutorial. I didn't really understand the method reference which led me to some internet-searching which led me to the Oracle Java tutorials and some reading time with the Java 8 documentation.

Result:


  1. I came up with the //...line. Both versions work fine.

  2. I understand that I don't understand the "from"-Method at all. (For example where does it get its data from?)



Which brings me to my main questions:

Is there a significant difference between those 2 versions which results in use-case-dependent best practices?

If yes, what would these cases be?

(If somebody could explain the first version a little bit further i would be happy.)

Any help is appreciated.

Answer

I also find the second one much clearer.

Let's try explaining the first one, though.

A DateTimeFormatter parses a String to something called a "TemporalAccessor", which is an object that you can query to get various date and time fields.

But most of the time you don't want a TemporalAccessor. You want a ZonedDateTime, or a LocalDate, or a LocalDateTime, for example. So, you need a strategy to transform a TemporalAccessor into the type you want.

This strategy is called a TemporalQuery.

TemporalQuery<R> is a functional interface, whose unique abstract method is

 R queryFrom(TemporalAccessor temporal)

So, as you see, it indeed allows transforming a TemporalAccessor into something else.

Once you have such a TemporalQuery, you can use the following method from DateTimeFormatter:

public <T> T parse(CharSequence text, TemporalQuery<T> query)

It will first parse the text to a TemporalAccessor, and then use the query to transform the TemporalAccessor into something else.

In your case, you want a LocalDate. You thus need an implementation of TemporalQuery<LocalDate>, i.e. a method which takes a TemporalAccessor and returns a LocalDate. LocalDate.from(TemporalAccessor) is such a method. So you can pass a reference to that method to the parse method and get a LocalDate (provided the TemporalAccessor, obtained from the text, contains the needed date information).

And in fact, that's exactly what the second line in your example does: its implementation is:

public static LocalDate parse(CharSequence text, DateTimeFormatter formatter) {
    Objects.requireNonNull(formatter, "formatter");
    return formatter.parse(text, LocalDate::from);
}
Comments