<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>Hi Tagir,<br>
I agree with all Kevin said. I'm also with you re. things being
inconsistent.</p>
<p>The reason as to why javac allows what it allows is that it
implements a more lax version of "unboxing" (mostly because of old
issues that were "fixed" in Java 6, see end of this email). E.g.
anything whose supertype is a boxed type can be unboxed, and so
type variables get caught in the mix.</p>
<p>But since String doesn't use unboxing conversion, there's no
special behavior there.</p>
<p>There's also other oddities and anomalies -- for instance:</p>
<p>```<br>
<X extends Integer> void m(Integer i, X x) {<br>
x++; // ok<br>
x = (Integer)x; // error<br>
}<br>
```<br>
<br>
The first statement being ok means that basically we know that X
can only be instantiated with Integer (as Integer is final). But
then why does the cast fail?</p>
<p>I think more work needs to be done on both sides (spec _and_
compiler) to flesh out this story in full.</p>
<p>Maurizio<br>
<br>
[1] - <a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/JDK-5043021">https://bugs.openjdk.org/browse/JDK-5043021</a><br>
[2] - <a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/JDK-6240565">https://bugs.openjdk.org/browse/JDK-6240565</a><br>
</p>
<div class="moz-cite-prefix">On 16/12/2025 08:04, Tagir Valeev
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CAE+3fjbGY+H5vSzL5vg3PPmcyiiv=d2kK7ywLcet0J3AwY4_uw@mail.gmail.com">
<div dir="ltr">Hello, Kevin!
<div><br>
</div>
<div>Indeed, this is helpful, thank you. It looks like, we
should support this case in IntelliJ IDEA as well. Here's
another sample that might be related:</div>
<div><br>
</div>
<div>private static <X extends String> void concat(X x) {<br>
System.out.println(x+1);<br>
}<br>
<br>
void main() {<br>
concat("hello");<br>
}<br>
</div>
<div><br>
</div>
<div>This code is not compilable, we have a compilation error:</div>
<div><br>
</div>
<div>java: bad operand types for binary operator '+'<br>
first type: X<br>
second type: int</div>
<div><br>
</div>
<div>It looks inconsistent to me that 'X extends Integer' is
being treated as Integer, but 'X extends String' is not being
treated as String. But probably it's a different case, as
unboxing is not involved here.</div>
<div><br>
</div>
<div>With best regards,</div>
<div>Tagir Valeev.</div>
</div>
<br>
<div class="gmail_quote gmail_quote_container">
<div dir="ltr" class="gmail_attr">On Tue, Dec 16, 2025 at
12:01 AM Kevin Bourrillion <<a href="mailto:kevin.bourrillion@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">kevin.bourrillion@oracle.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
Hey Tagir, we were discussing this internally a couple
months ago, and I felt there was a general consensus that
this is indeed a spec bug. Javac's permissiveness
seems totally reasonable here.</div>
<div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
We either need to insert more WRCs before unbox
conversions (like the one you found), or (a
seemingly-simpler approach that I hope will work) just
tweak the specification of unboxing conversion itself so
it applies to any
<i>subtype</i> of Integer-etc., instead of only the exact
type. (Of course this also affects intersection types and
capture types as well as the case in your example.)</div>
<div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
We didn't jump on fixing it yet but it's slated to happen
sooner or later as part of a series of type-conversion
cleanups we're working on. Hopefully just getting this
answer unblocks you for now?</div>
<div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div id="m_-2918854146287893194mail-editor-reference-message-container">
<div style="text-align:left;padding:3pt 0in 0in;border-width:1pt medium medium;border-style:solid none none;border-color:rgb(181,196,223) currentcolor currentcolor;font-family:Aptos;font-size:12pt;color:black">
<b><br>
<p style="font-family:Calibri;font-size:10pt;color:rgb(0,0,0);margin:5pt;font-style:normal;font-weight:normal;text-decoration:none" align="Left">
Confidential- Oracle Internal<br>
</p>
From: </b>compiler-dev <<a href="mailto:compiler-dev-retn@openjdk.org" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">compiler-dev-retn@openjdk.org</a>>
on behalf of Tagir Valeev <<a href="mailto:amaembo@gmail.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">amaembo@gmail.com</a>><br>
<b>Date: </b>Monday, December 15, 2025 at 9:21 AM<br>
<b>To: </b><a href="mailto:compiler-dev@openjdk.org" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">compiler-dev@openjdk.org</a>
<<a href="mailto:compiler-dev@openjdk.org" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">compiler-dev@openjdk.org</a>><br>
<b>Subject: </b>Unboxing conversion of generic types
with box as a bound<br>
<br>
</div>
<div dir="ltr">Hello!</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">I noticed that the following program is
compilable without errors using OpenJDK 25 javac:</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">private static <X extends Integer>
void add(X x) {<br>
System.out.println(+x);<br>
}<br>
<br>
void main() {<br>
add(10);<br>
}</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">I wonder if it's correct. The JLS 15.15.3
says [1]:</div>
<div dir="ltr"><br>
The type of the operand expression of the unary +
operator must be a type that is convertible (§5.1.8) to
a primitive numeric type, or a compile-time error
occurs.<br>
<br>
</div>
<div dir="ltr">The JLS 5.1.8, in turn, says [2]:</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">Unboxing conversion treats expressions of a
reference type as expressions of a corresponding
primitive type. Specifically, the following eight
conversions are called the unboxing conversions:<br>
...</div>
<div dir="ltr">From type Integer to type int<br>
...</div>
<div dir="ltr">At run time, unboxing conversion proceeds
as follows:</div>
<div dir="ltr">...</div>
<div dir="ltr">If r is a reference of type Integer, then
unboxing conversion converts r into r.intValue()<br>
<br>
</div>
<div dir="ltr">In my case, the type of reference is X,
rather than Integer. So my question, should I read 'type
Integer' here as 'type Integer, or any generic type
whose upper bound is type Integer'? In other words,
should we assume that the X type declared as `X extends
Integer` is convertible to a primitive numeric type? It
looks like, here a widening reference conversion (5.1.5)
happens before an unboxing conversion, but 15.15.3 does
not say about widening reference conversion. I've also
checked 5.6 "Numeric contexts", but it also does not
mention that before unboxing conversion, a widening
reference conversion might occur. </div>
<div dir="ltr"><br>
</div>
<div dir="ltr">Could anybody please clarify whether the
compiler is wrong or I read the specification
incorrectly? Thank you in advance!</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">With best regards,</div>
<div dir="ltr">Tagir Valeev</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">[1] <a href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-15.html#jls-15.15.3" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">
https://docs.oracle.com/javase/specs/jls/se25/html/jls-15.html#jls-15.15.3</a></div>
<div dir="ltr">[2] <a href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-5.html#jls-5.1.8" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">
https://docs.oracle.com/javase/specs/jls/se25/html/jls-5.html#jls-5.1.8</a></div>
</div>
</div>
</blockquote>
</div>
</blockquote>
</body>
</html>