Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6558557

Overhaul specification of unchecked casts

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P5 P5
    • 7
    • 5.0, OpenJDK6
    • specification
    • None
    • rc
    • generic, unknown
    • generic, linux
    • Verified

      [Merged the description from 6717221]

      Consider the following program:

      import java.util.*;
      class cast {
        Iterable<? extends Number> x1 = null;
        Collection<? extends Number> x2 = (Collection<? extends Number>)x1; // javac generates a warning here
      }

      The JLS seems to mandate a warning (JLS 5.5) for a cast that can be considered 'statically-safe':

      "A cast from a type S to a parameterized type (§4.5) T is unchecked unless at least one of the following conditions hold:
      1) S <: T.
      2) All of the type arguments (§4.5.1) of T are unbounded wildcards.
      3) T <: S and S has no subtype XT , such that the erasures (§4.6) of X and T are the same. "

      Here we have that:

      1) S (Iterable<? extends Number>) is *not* a subtype of T (Collection<? extends Number>)
      2) T's type argument (? extends Number) is *not* an unbounded wildcard
      3) There are *infinite* subtypes of S of the kind J = Collection<? extends K>, with K <: Number, such that |J| == |T|

      Thus the JLS wants the cast to raise a warning, when there is no need. In the following program, the JLS also wants a warning and javac doesn't give one:

      class I1<T> {}
      class I2<T> extends I1<T> {}
      class Main {
        void f(I1<Integer> i1) { Object o = (I2<? extends Number>) i1; }
      }

      The code is safe and no warning is logically "necessary" because no heap pollution can result from the cast at runtime, but it is a shortcoming of the specification that it doesn't justify javac's behavior. In short, it is both a javac bug (it doesn't comply with the specification) and a specification bug (the spec should justify javac's current behavior).

      This area of the JLS would benefit from an overhaul.

      On 1/7/07, ... wrote:
      We issue an unchecked cast warning on this:
              
              interface I1<T> {}
              class GC22<T> implements I1<T> {}
              class A {
                       I1<Short>[] x = null;
                       GC22<? extends Number>[] y = (GC22<? extends Number>[])x;
              }
              
              but javac doesn't. Is this because the rules in JLS 5.5 about unchecked
              casts refer to parameterized types, and an array of a parameterized type
              doesn't count as a parameterized type?

            abuckley Alex Buckley
            ahe Peter Ahe
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: