JDK-8254324 : [JEP 390] Deprecate wrapper class constructors for removal
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.lang
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 16
  • Submitted: 2020-10-09
  • Updated: 2020-12-13
  • Resolved: 2020-11-18
Related Reports
CSR :  
Description
Summary
-------

The primitive wrapper constructors are being deprecated for removal, they have been deprecated since JDK 9.

The classes with constructors to be deprecated for removal are java.lang.Boolean, java.lang.Byte, java.lang.Character, java.lang.Short, java.lang.Integer, java.lang.Long, java.lang.Float, and java.lang.Double.

Problem
-------

The Valhalla project aims to unify the primitive and class-based type systems of Java by introducing *primitive classes*, whose instances lack identity. As part of this unification, the primitive wrapper classes will be repurposed so that rather than _wrapping_ the existing primitive values, they will _represent_ the primitive values directly���that is, the existing primitive values will be considered identity-free instances of these classes.

[JEP 390](https://openjdk.java.net/jeps/390) anticipates these changes by introducing warnings about code that may no longer work properly when certain classes of the Java Platform API, including the wrapper classes, become primitive classes.

In particular, while a primitive class has constructors, the semantics of those constructors are different: a unique identity is not produced with each invocation. Instead, instances whose fields have the same values are considered `==`.

In addition, primitive class constructors are *not* encoded in class files using instance initialization methods. Existing binaries that attempt to invoke a method like `Integer.<init>:(I)V` will encounter `LinkageError`s.

In the future, to minimize surprises due to these changes, the primitive wrapper constructors will be made private, and all clients will be required to get instances through literals, primitive operations, or the `valueOf` and `parse*` methods. These alternative methods never promise to produce an instance with a unique identity.

As a first step, the primitive wrapper constructors are being marked for removal.

Solution
--------

The @Deprecated annotations will include "forRemoval = true". This will draw attention to the coming accessibility reduction and give clients an opportunity to update their code.

We expect most projects under active development will respond by updating their code (if they have not already). That said, usage of these constructors is widespread. For those projects or legacy binaries that don't get updated, we'll investigate tooling in a future release that will allow users to adapt to the removal by opting in to bytecode rewrites, replacing constructor calls with `valueOf` calls.


Specification
-------------

These constructors will be annotated to deprecate for removal.

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Boolean(boolean) {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Boolean(java.lang.String) {...}
    
    @Deprecated(since="9", forRemoval = true)
    public java.lang.Byte(byte) {...}
    
    @Deprecated(since="9", forRemoval = true) 
    public java.lang.Byte(java.lang.String) throws java.lang.NumberFormatException {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Character(char) {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Short(short) {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Short(java.lang.String) throws java.lang.NumberFormatException {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Integer(int) {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Integer(java.lang.String) throws java.lang.NumberFormatException {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Long(long) {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Long(java.lang.String) throws java.lang.NumberFormatException {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Float(float) {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Float(double) {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Float(java.lang.String) throws java.lang.NumberFormatException {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Double(double) {...}

    @Deprecated(since="9", forRemoval = true)
    public java.lang.Double(java.lang.String) throws java.lang.NumberFormatException {...}

Comments
Moving this CSR to Approved after the JEP has been further updated with stronger compatibility guidance in its Dependencies section: > Another prerequisite to making the wrapper classes primitive classes > is sufficient tooling to identify and work around legacy uses of their > constructors. Two followup features will be investigated in separate > JEPs: > > * HotSpot runtime warnings for usages of deprecated APIs, including the wrapper class constructors. This would complement the warnings > produced by javac and jdeprscan. > > * Tooling to support execution of binaries that are unable to update their usages of wrapper class constructors. This might, for example, > give programmers the option to rewrite their bytecodes to make use of > the valueOf factory methods.
18-11-2020

JEP 390 description has been updated (see "Motivation") to summarize the impact of constructor removal and justify deprecation for removal now.
07-11-2020

Yes, thanks for the reminder. I'll update the JEP.
03-11-2020

The source and binary compatibility implications of this work can be expected to be a core concern of recipients of the warnings in question. A mailing list thread has much less visibility than the text of a JEP. Please update the JEP text to summary the plan of record for handing source and binary updates in the future. Marking the JEP as pended to indicate that to-do; please re-Finalize after the JEP is updated.
03-11-2020

See the valhalla-spec-experts mailing list for further discussion about the eventual compatibility impact of *removing* the constructors, and mitigation strategies: https://mail.openjdk.java.net/pipermail/valhalla-spec-experts/2020-October/001430.html
28-10-2020