1

As far as I know Integer, for example, has cached instances with a value of -128 to 127. This is a JLS requirement. JLS 5.1.7:

If the value p being boxed is the result of evaluating a constant expression (§15.29) of type boolean, byte, char, short, int, or long, and the result is true, false, a character in the range '\u0000' to '\u007f' inclusive, or an integer in the range -128 to 127 inclusive, then let a and b be the results of any two boxing conversions of p. It is always the case that a == b.

So I can understand the point of using Integer.valueOf() or Long.valueOf() instead of creating instances with a new operator. Using valueOf() returns fixed instances with values from -128 to 127. In this case, I can even compare two objects using the == operator. Moreover I can increase upper range of cache with -XX:AutoBoxCacheMax=<size> java option.

But I can't figure out why the new Float() and new Double() are deprecated? Neither Float nor Double has a cache. And the valueOf() operator returns the instance created with the new operator.

According to the JDK documentation, I should use the static factory methods Float.valueOf() or Double.valueOf() instead of new Float() or new Double() and I'll have "significantly better space and time performance". But where are they?

/**
 * Constructs a newly allocated {@code Double} object that
 * represents the primitive {@code double} argument.
 *
 * @param   value   the value to be represented by the {@code Double}.
 *
 * @deprecated
 * It is rarely appropriate to use this constructor. The static factory
 * {@link #valueOf(double)} is generally a better choice, as it is
 * likely to yield significantly better space and time performance.
 */
@Deprecated(since="9")
public Double(double value) {
    this.value = value;
}

/**
 * Returns a {@code Double} instance representing the specified
 * {@code double} value.
 * If a new {@code Double} instance is not required, this method
 * should generally be used in preference to the constructor
 * {@link #Double(double)}, as this method is likely to yield
 * significantly better space and time performance by caching
 * frequently requested values.
 *
 * @param  d a double value.
 * @return a {@code Double} instance representing {@code d}.
 * @since  1.5
 */
@HotSpotIntrinsicCandidate
public static Double valueOf(double d) {
    return new Double(d);
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Denis A
  • 21
  • 4
  • Since Java 9, the constructors have been deprecated. – Mark Rotteveel Apr 03 '22 at 12:47
  • 1
    @ElliottFrisch+MarkRotteveel Read the question. – Boann Apr 03 '22 at 12:47
  • @Boann My comment answers the question in the title (you should use `Double.valueOf` because the constructor is deprecated), while the duplicate answers the question in the body of the question. – Mark Rotteveel Apr 03 '22 at 12:49
  • 4
    Note the `@HotSpotIntrinsicCandidate` annotation on the method. Which indicates that the (hotspot) JVM **might** replace this method with hand written assembly or similar. So it doesnt have to actually execute the Java code you see there, it might use **better** code under the hood. (Whether it does this as of today or not is a different story) – Zabuzard Apr 03 '22 at 13:11

1 Answers1

2

They assumed that they might one day add a cache, in which case the advice would be correct. But it never happened, and probably never will, so it makes no difference.

Boann
  • 48,794
  • 16
  • 117
  • 146