Unchecked conversion spec

Tagir Valeev amaembo at gmail.com
Mon Jan 16 16:17:18 UTC 2023


Hello!

I have trouble understanding the unchecked conversion section of JLS
(5.1.6.2)[1].
I have the following code:

import java.util.function.Supplier;

public class Test {
static class Box<T extends CharSequence> implements Supplier<T> {
@Override
public T get() {
return null;
}
}

<S extends Supplier<String>> void typeArg(S s) {
Box<String> b = (Box<String>) s;
}
}

javac with -Xlint:all compiles it without unchecked warning (tried
various versions from JDK 11 to JDK 20ea, the behavior is the same).
The spec says:

The unchecked narrowing reference conversions are as follows:

A narrowing reference conversion from a type S to a parameterized
class or interface type T is unchecked, unless at least one of the
following is true:
- All of the type arguments of T are unbounded wildcards.
- T <: S, and S has no subtype X other than T where the type arguments
of X are not contained in the type arguments of T.

In my example, T = Box<String> and S = S. To my understanding, "All of
the type arguments of T are unbounded wildcards." is false (<String>
is bounded), and Box<String> is not a subtype of S, so "T <: S" is
wrong. This means that this conversion should be unchecked and a
warning should be issued.

I feel that javac behavior is correct. Probably I don't understand the
spec correctly. Could you please help me with this?

Thank you in advance,
Tagir Valeev.

[1] https://docs.oracle.com/javase/specs/jls/se19/html/jls-5.html#jls-5.1.6.2


More information about the compiler-dev mailing list