Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does java.time use 'of' instead of 'new' for dates? [duplicate]

In the new date package in Java 8, we changed from using "new Date()" to "LocalDate.of()".

Date d = new Date(year, month, dayOfMonth);            //Old way
LocalDate d2 = LocalDate.of(year, month, dayOfMonth);  //new way

When you want a new object you usually use the new keyword. This is an intuitive way to create a new object.

Sometimes, when you need a singleton with delayed initialization you can use a static method to get the instance. In this case you must call it getInstance() so developers know what to expect.

This new syntax makes the code less intuitive. It forces you to learn how to deal with specific objects instead of simply using them.

Are there any good reasons under the hood for this change?

like image 456
David Marciel Avatar asked Jan 24 '20 08:01

David Marciel


2 Answers

Usually static factory methods are preferred to constructors for several reasons,

  • They have a name and that makes your code much more readable.
  • static factory methods can have covariant return types, but constructor can't. This allows your API users to work with the interface, not the implementation, allowing you more room to change the concrete types in future releases. Also it reduces the conceptual surface area of the API too.
  • Unlike constructors, static factory methods can do certain optimizations. On the contrary, every time you call a constructor, you expect it to return a new object. For an instance, check out the implementation of the static factory method Collections.emptyList();
public static final List EMPTY_LIST = new EmptyList<>();

public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

It eagerly creates a singleton list and returns it on every invocation saving unnecessary overhead that would occur when constructors were used.

Due to the above reasons, static factories are preferred to constructors in today's programming. However, you can still use the new keyword with constructors as circumstances warrant.

like image 106
Ravindra Ranwala Avatar answered Sep 23 '22 14:09

Ravindra Ranwala


There is a problem with new: your code depends on the concrete class. Thus changing/evolving the code is a more difficult task.

A factory is much more manageable because (1) the user code is not dependant on the concrete type (2) the code that choose the concrete type is in a single place. Then the final code is much more secure/evolvable, etc.

getInstance() is not a good name for a factory, it is more the name of a singleton method. "get" is not intended to create something, just to get something already existant. createInstance or create is much more explicit for factories (many of them, even in Java are called such - examine createImage and alike). But alas, for reasons explicited by @slaw in comments, you need to be more precise to help the user choose between argument semantic, thus things like createFromYears, createFromMinutes, etc. That may be slightly verbose, then of seems to be a good compromise. Finally it is more easy (IMHO) to use of*() than createImage() with a lot of parameters to explain what arguments are...

like image 43
Jean-Baptiste Yunès Avatar answered Sep 23 '22 14:09

Jean-Baptiste Yunès