JDK-6557279 : Tweak provable distinctness
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-05-14
  • Updated: 2014-02-26
  • Resolved: 2011-07-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 rcFixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
http://forum.java.sun.com/thread.jspa?forumID=316&threadID=634688

https://bugs.eclipse.org/bugs/show_bug.cgi?id=99107

public final class A<B> {
  void doit() {
    Class<A> clazz1 = (Class<A>) this.getClass();
    Class<A<B>> clazz2 = (Class<A<B>>) clazz1;
    clazz2.getName();
  }
}

Sun's javac (1.5.0_03) gives an error:

A.java:5: inconvertible types
found   : java.lang.Class<A>
required: java.lang.Class<A<B>>
    Class<A<B>> clazz2 = (Class<A<B>>) clazz1;
                                       ^

------- Additional Comment #1 From Philippe Mulet 2005-06-09 06:11 [reply] -------

According to the spec, cast conversion is allowed since the types are
not probably distinct.

I thus believe this is a bug in javac.
Another example where non-provably distinct types are treated as distinct:

import java.io.*;
import java.util.*;
public class X {
    public static void main(String[] args) {
        LinkedList<String> linkedList= new LinkedList<String>();
        List<? extends Serializable> a = linkedList;
        List<Runtime> d = (LinkedList<Runtime>) a; // inconvertible! ??
    }
}

PPM says: "Javac thinks it is inconvertible, I think it should only be an unchecked cast.
Basically List<capture-of-? extends Serializable> is not provably distinct from List<Runtime>
this comes from the fact when recursing into the algorithm an implementation of Serializable may well subclass Runtime (hence you cannot complain for sure)."

Comments
EVALUATION Whether the cast from Class<A> to Class<A<B>> should succeed depends to whether A and A<B> are provably distinct. They are, because a raw type is not the same as a generic type. The cast should fail. Similarly, the code at [1] casts from Collection<Class> to Collection<? extends Class<?>>. There may be a case for following the precedent of unchecked conversion, by treating Class and Class<?> as the same due to the unbounded wildcard. This would deny provable distinctness and allow the cast. However, unchecked conversion is for compatibility with raw types, and we have two invocations of a generic type (Collection) in hand, so I see little reason to treat Class and Class<?> the same. The cast should fail. JLS 4.5.1.1 should be clarified along these lines: "Two type arguments are provably distinct if one of the following is true: - Neither argument is a type variable or wildcard, and the two arguments are not the same type. - One type argument is a type variable or wildcard, with an upper bound (from capture conversion, if necessary) is S; and the other type argument T is not a type variable or wildcard; and neither |S|<:|T| nor |T|<:|S|. - Each type argument is a type variable or wildcard, with upper bounds (from capture conversion, if necessary) of S and T; and neither |S|<:|T| nor |T|<:|S|." As for whether a List<? extends Serializable> can be cast to a List<Runtime>, what distinctness rules can possibly make this work, given that Serializable and Runtime are not compatible? [1] http://dertompson.com/index.php/2007/12/27/differences-between-java-compilers/
29-05-2007

EVALUATION Notice that the compiler will issue two diagnostics when run with -Xlint:all, see CR 6557182. I am skeptical that this is a bug as neither type is a subtype of each other. Moved to java/specification.
14-05-2007