> On Oct 19, 2020, at 6:01 PM, Dan Smith <daniel.sm...@oracle.com> wrote:
> 
> In the context of the Warnings for Value-Based Classes JEP, we're looking for 
> usages of the deprecated wrapper class constructors ('new Integer(...)', 'new 
> Double(...)', etc.). When do these get used? How often is this motivated by 
> wanting a unique object vs. legacy code that has no particular reason not to 
> use 'valueOf'?
> 
> We've got some investigations going on at Oracle, including looking at some 
> open-source projects, but I'm interested in examples from other 
> companies/projects as well. Please investigate and share what you find!
> 
> I'll reply in a few days with our analysis for the code we look at.

So, some conclusions that we've drawn:

- In 2020, the constructor calls are fairly pervasive, even in recently 
released binaries. Removing these constructors may be the most disruptive 
single API change we've ever made.

- The trend is good—serious projects have mostly responded to the deprecation 
warnings introduced in 9. In 2024 (for example), the picture may be much better.

- It is impossible, given the current JVM model for primitive classes, for 
Integer to both be a primitive class and support 'new java/lang/Integer'. 
Binaries calling the deprecated constructors simply won't work.

- There is a meaningful semantic difference, in terms of promising unique 
identity, between code that does 'new Integer' and code that does 
'Integer.valueOf' or implicitly boxes. The latter is better aligned with the 
class's future behavior as a primitive class.

- Almost no usages care about the identity distinction—they just want boxing. 
But it's difficult to automatically detect the usages that do.

These points lead to the following tentative plan:

We'll proceed as planned with deprecation for removal. The message for all Java 
programs is to stop using these constructors if you want to run in future JDKs. 
Typically, the simplest refactoring is to replace 'new Integer(x)' with just 
'x', but in some cases you might want 'Integer.valueOf(x)'. When you refactor, 
you should confirm that the change in identity semantics is acceptable.

We'll encourage IDEs to provide tooling for updating sources, including batch 
processing. (As an example, IntelliJ already highlights deprecated APIs and 
suggests conversions, although I'm not familiar with its batch processing 
features.)

For legacy binaries that have not been updated but that need to run on a future 
JDK, we'll provide tooling to rewrite their bytecode containing constructor 
calls, either as a preprocessing step on jar files, or as a runtime 
command-line argument.

This tooling will support common bytecode patterns like 'new Foo; dup; ...; 
invokespecial Foo.<init>;', but will not be a comprehensive solution. 
(Mimicking the behavior of instance initialization method invocation in full 
generality would be a very difficult task.) It will also carry behavioral 
compatibility risks. For these reasons, it will be available as a workaround, 
not as default JVM behavior.

Reply via email to