JDK-6270073 : Specification of casts involving final type is too strict
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Future Project
  • OS: generic
  • CPU: generic
  • Submitted: 2005-05-13
  • Updated: 2011-02-26
  • Resolved: 2011-02-26
Related Reports
Relates :  
Relates :  
Description
Javac incorrectly accepts this program in violation
of the spec:

class Test<S> {
        void foo() {
                A a = new A();
                Comparable<Object> c = (Comparable<Object>)a; // Fails as expected
                Comparable<S> c2 = (Comparable<S>)a; // Should fail?
        }
        
}

final class A implements Comparable<A> {
        public int compareTo(A o) {
                return 0;
        }
}

###@###.### 2005-05-13 15:37:27 GMT
This appears to be a specification bug so I have changed
the synopsis and reassigned the bug.

Comments
EVALUATION It has been proposed that JLS 5.5 should replace: "If S is a final class, then S must implement T, or a compile-time error occurs." with: "If S is a final class (��8.1.1), then |S| <: |T|, or a compile-time error occurs. Furthermore, if there exists a supertype X of T, and a supertype Y of S, such that both X and Y are provably distinct parameterized types (��4.5), and that the erasures of X and Y are the same, a compile-time error occurs." (The boilerplate about 'provably distinct' stops a cast from (a class that implements) Comparable<String> to Comparable<Integer>, for example.) However, Comparable<A> and Comparable<S> are not provably distinct, under either JLS3 or the tweaked provable distinctness in 6557279. So the second cast, from Comparable<A> to Comparable<S>, will not fail. To make Comparable<A> and Comparable<S> provably distinct feels risky. I am inclined to leave the spec as is.
08-12-2006

SUGGESTED FIX If this isn't a specification issue, the compiler fix is this: if ((t.tsym.flags() & INTERFACE) == 0) { if ((s.tsym.flags() & INTERFACE) != 0 && (t.tsym.flags() & FINAL) != 0) return isSubType(s,t); } The compiler has, most unfortunately, swapped s and t.
16-09-2005

EVALUATION This could be a spec bug.
16-09-2005

EVALUATION Yes, the cast implementation is wrong. ###@###.### 2005-05-13 15:37:27 GMT
13-05-2005