Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
* Casting contexts allow the use of ***one of the following***: - a widening and narrowing primitive conversion (5.1.4) // Missing; reported by Neal and J.Stephen Adamcyzk - a boxing conversion (5.1.7) optionally followed by a widening reference conversion (5.1.5) // Extension of existing clause - an unboxing conversion (5.1.8) optionally followed by a widening primitive conversion (5.1.2) // Extension of existing clause - a widening reference conversion (5.1.5) optionally followed by either an unboxing conversion (5.1.8) or an unchecked conversion (5.1.9) // Extension of existing clause, as per 6558543 - a narrowing reference conversion (5.1.6) optionally followed by either an unboxing conversion (5.1.8) or an unchecked conversion (5.1.9) // Extension of existing clause, as per 6558543 (The detailed rules for casting must also change to reflect the updated list.) * A cast from a type S to a type variable T is unchecked unless S<:T (Not "A cast to a type variable is always unchecked.") * If S is an interface type: If T is an array type, then a compile-time error occurs unless S is the type java.io.Serializable or the type Cloneable, the only interfaces implemented by arrays. If T is a type that is final, then: If S is not a parameterized type or a raw type, then T must implement S, or a compile-time error occurs. When the source type is an intersection type S = A1 & A2 & ... & An, the success of the cast should be determined by the most restrictive component of the intersection type. That is, if there exists an Ai (i:1..n) which is not convertible into the target type T, then the cast should fail. (Corresponds to compiler CR 6557182; see comments therein.) Josh reported a problem where highlights the lack of cast conversion rules for nested types: class Outer<E> { Inner inner; Outer(E e) { inner = new Inner(e); } class Inner { E e; Inner(E e) { this.e = e; } E getOtherElement(Object other) { Inner that = (Inner) other; // Shouldn't this generate a warning? return that.e; } } public static void main(String[] args) { Outer<String> s = new Outer<String>("hovercraft"); Outer<Integer> i = new Outer<Integer>(1234); // The next line produces a ClastCastException at runtime! String producesClassCast = s.inner.getOtherElement(i.inner); } } It compiles, as of javac 1.6.0_06, without generating a warning, and the compiler-generated cast fails at runtime for: String producesClassCast = s.inner.getOtherElement(i.inner); This appears to violate Java's "cast iron guarantee." Luckily, the compiler is simply failing to generate an unchecked cast warning on line 16: Inner that = (Inner) other; // Shouldn't this generate a warning? The problem is that Inner (in this context) refers to Outer<E>.Inner, so we're casting from Object to a parameterized type. JLS clarification is required. javac in JDK7 rightly gives a warning: Test.java:12: warning: [unchecked] unchecked cast found : java.lang.Object required: Outer<E>.Inner Inner that = (Inner) other; // Shouldn't this generate awarning? ^
|