-
Bug
-
Resolution: Fixed
-
P2
-
5.0
-
b48
-
generic
-
solaris_8
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
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
- relates to
-
JDK-6184881 Object.getClass() typing rule could be improved
-
- Open
-