United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4982096 : Object.getClass() leads to type system loophole

Details
Type:
Bug
Submit Date:
2004-01-22
Status:
Resolved
Updated Date:
2004-04-16
Project Name:
JDK
Resolved Date:
2004-04-16
Component:
tools
OS:
solaris_8
Sub-Component:
javac
CPU:
generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
5.0
Fixed Versions:
5.0 (b48)

Related Reports
Relates:

Sub Tasks

Description
There is a loophole in the type system that is present because
we made getSuperclass() return a Class with an argument of a generic
type.  This comes about because of a cast() operation we recently
added to class Class:

2384     /**
2385      * Casts an object to the class or interface represented
2386      * by this <tt>Class</tt> object.
2387      *
2388      * @param obj the object to be cast
2389      * @return the object after casting, or null if obj is null
2390      *
2391      * @throws ClassCastException if the object is not
2392      * null and is not assignable to the type T.
2393      *
2394      * @since 1.5
2395      */
2396     public T cast(Object obj) {
2397         if (obj != null && !isInstance(obj))
2398             throw new ClassCastException();
2399         return (T) obj;
2400     }

The loophole works like this:

    class A extends List<Integer> {}

    List<String> ls = new List<String>();
    List<Integer> li = 
                  A.class.getSuperclass() // Class<List<Integer>>
                  .cast(ls);
    li.add(1);
    String s = ls.get() // BANG!

We can either remove the cast() operator (which would be a shame - it
is really useful - see 4881275) or make the class type returned by
A.class.getSuperclass be Class<List> instead of Class<List<Integer>>.


----------------
See Evaluation section for corrected type loophole snippet.

###@###.### 2004-04-02


                                    

Comments
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
tiger-beta2

FIXED IN:
tiger-beta2

INTEGRATED IN:
tiger-b48
tiger-beta2


                                     
2004-06-14
PUBLIC COMMENTS

...
                                     
2004-06-10
EVALUATION

Actually, there is no compiler magic in getSuperclass() that would lead to a
type loophole.  If you try the example in the description you'll see why.
However, there IS a problem due to the interaction of getClass() and
cast(), and due to the interaction of class literals of generic types and
cast().  We can fix these by requiring that all values of type Class<>
generated by these techniques erase the argument type.  A spec based on this
scheme is awaiting CCC approval.

###@###.### 2004-02-27


Here's the real type loophole in action:

	List<String>  ls = new ArrayList<String>();
	List<Integer> li = new ArrayList<Integer>();

	li = li.getClass().cast(ls);	// no unchecked assignment warning
	li.add(1);
	String s = ls.get(0);	// BANG!

###@###.### 2004-04-02


Parameterized class literals are already disallowed by the grammar.
We should also disallow parameterized types from being used in
instanceof expressions, since there's nothing that can be done with 
the type arguments at run time.

###@###.### 2004-04-02

                                     
2004-04-02



Hardware and Software, Engineered to Work Together