Search code examples
javajls

JLS: section 5.2 Assignment Conversion (chain of conversions)


I'm trying to understand the example from JLS.

This section reads:

It is a compile-time error if the chain of conversions contains two parametrized types that are not in the subtype relation.

An example of such an illegal chain would be:

Integer, Comparable<Integer>, Comparable, Comparable<String>

The first three elements of the chain are related by widening reference conversion, while the last entry is derived from its predecessor by unchecked conversion. However, this is not a valid assignment conversion, because the chain contains two parametrized types, Comparable<Integer> and Comparable<String>, that are not subtypes.

In what conditions we cat get this chain? Can somebody give some more verbose example?


Solution

  • I believe I've made some sense of it.

    Assignment contexts apply to assignment expressions.

    In the expressions

    Integer integerValue = 42;
    Comparable<Integer> comparableInteger = integerValue;
    

    the integer literal 42 can be assigned to a variable of type Integer through a boxing conversion. A value of type Integer can be assigned to a variable of type Comparable<Integer> through widening reference conversion.

    In the following expression

    Comparable raw = comparableInteger;
    

    a value of type Comparable<Integer> can be assigned to a variable of type Comparable through widening reference conversion.

    But you cannot do

    Comparable<String> comparableString = integerValue;
    

    because that would require an unchecked conversion from Comparable to Comparable<String>, which is not necessarily bad, except when

    the chain of conversions contains two parametrized types that are not in the subtype relation

    You could have done

    Comparable raw = comparableInteger;
    Comparable<String> parameterized = raw;
    

    and that will use unchecked conversion (and potentially a ClassCastException at runtime when you try to invoke compareTo). However, there is no issue at compile time because the chain of conversions was simply

    Comparable, Comparable<String>
    

    which is allowed.