Source code analysis: calls to wrapper class constructors

forax at univ-mlv.fr forax at univ-mlv.fr
Wed Oct 28 12:48:34 UTC 2020


----- Mail original -----
> De: "daniel smith" <daniel.smith at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "valhalla-spec-experts" <valhalla-spec-experts at openjdk.java.net>
> Envoyé: Mardi 27 Octobre 2020 21:36:21
> Objet: Re: Source code analysis: calls to wrapper class constructors

>> On Oct 27, 2020, at 2:00 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>> 
>> Three remarks:
>> - the compiler can warn because a code is using new Integer(value) or warn
>> because the compiler will automatically transform all new Integer(value) to
>> Integer.valueOf() once Valhalla is integrated,
>>  i prefer the second solution, having a warning message saying that in the future
>>  new Integer() will not be supported and that all new Integer(...) will be
>>  transformed by the compiler automatically to Integer.valueOf().
> 
> I think the idea here is that if the compiler were doing this today, it would
> reduce the amount of binaries that will fail in the future. But... it won't
> eliminate the problem. I think we'd still need to do something about binaries
> that are *already* published (e.g., JUnit 4.12), or that target a pre-16 JDK.
> 
> So given that a workaround for binaries will exist, there's not a lot to be
> gained by complicating the source-level story. And in the minus column, some
> areas of concern:
> 
> - We'd have to change the language in 16 to special-case what class instance
> creation expressions mean.
> 
> - We'd be breaking behavioral compatibility, with no way to opt out (if, say,
> you need unique identities, and don't plan to deploy on future JDKs).
> 
> - There's no change in the compile-time experience—using either deprecation or
> these special warnings, you'd be stuck with warnings until you rewrote your
> code.
> 
> Treating this as a standard application of deprecation, with behavioral changes
> triggered by source code changes, seems like a more attractive solution.

[...]

If the VM change all new Integer(x) to Integer.valueOf(x), see my other mail on how to do it, then i think the language should mirror the VM behavior.

The warning doesn't have to be that the compiler actually rewrite new Integer(x) to Integer.valueOf(x) but that in the future the compiler will rewrite new Integer(x) to Integer.valueOf(x).
The rewrite by the compiler has to be done at the same time ==/acmp transition from meaning pointer comparison to meaning primitive object comparison is both sides are primitive objects.

The idea is that at a point in time, doing a new on a primitive object class is illegal, so the verifier will reject any use of "new java/lang/Integer"
At that time,
 - the compîler will rewrite new Integer(x) to Integer.valueOf(x), so the generated class is valid and the source code is still valid but the semantics has slightly change hence the warning.
 - the VM will rewrite new Integer(x) to Integer.valueOf(x) for all classfile with a version lower than the current version.

It's a better plan because it means that Java 1.0+ code still compile and that the compiler behavior and the VM behavior are aligned.

It works because the semantics of the primive object subtype of java.lang.Integer and the semantics of java.lang.Integer has an identity object are mostly similar.
It also means that the warning on synchronized(Integer) will now be an error.

regards,
Rémi


More information about the valhalla-spec-observers mailing list