-
Bug
-
Resolution: Fixed
-
P4
-
5.0, 6
-
b51
-
generic, x86
-
generic, linux
-
Verified
FULL PRODUCT VERSION :
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b98)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b98, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux coco-laptop 2.6.15-26-686 #1 SMP PREEMPT Thu Aug 3 03:13:28 UTC 2006 i686 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
In the exact construct used in the Collections.emptyList() method, javac fails to raise an unchecked warning where it should. The test case shows the bug; and it also shows that an equally uncheckable cast, without a subtype introduced, does raise the warning.
It seems to appear to me that the author of the collections class may have used this technique thinking that since the returned object never operates on any object of its type argument type that it turns out to be safe to perform this cast. Unfortunately it must lead to a warning.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create some generic class.
2. Create a subclass with a given type argument type.
3. Create an instance of the subclass.
4. Cast the subclass to the superclass type with some other generic argument type.
The case will not raise a warning though it should.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The unchecked warning.
ACTUAL -
No warning.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
If the casted object does in fact contain some reference of a type not matching the type given in the cast expression then a runtime exception can occur.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
(Compile this class with the "-Xlint" option and see that no warnings are raised. Then run it and see a runtime exception due to an unchecked erroneous cast. Uncomment the optional code to see another path to attempting the same cast which does raise a warning.)
// A generic class:
public class TypedCastBug<T> {
// A parameterized subclass, typed with Object:
static class Child extends TypedCastBug<Object> { }
// ** This method performs an unchecked cast that javac
// erroneously does not issue a warning for:
static <U> TypedCastBug<U> create() {
Child child = new Child();
child.set(new Object());
return (TypedCastBug<U>) child;
}
// Run this to see a runtime exception caused through the cast in create():
public static void main(String[] args) {
TypedCastBug<Number> c = create();
Number n = c.get();
}
// Instance data and methods:
T t;
void set(T t) { this.t = t; }
T get() { return t; }
// An example of a similar API that does cause javac to raise a warning:
// static TypedCastBug<Object> willWarn = new TypedCastBug<Object>();
// static <U> TypedCastBug<U> raisesTheWarning() {
// return (TypedCastBug<U>) willWarn; // Effectively the same as above
// }
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Note that any cast to a parameterized type is not checkable:
(List<XXX>)
The actual argument type (XXX) is not known at runtime.
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b98)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b98, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux coco-laptop 2.6.15-26-686 #1 SMP PREEMPT Thu Aug 3 03:13:28 UTC 2006 i686 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
In the exact construct used in the Collections.emptyList() method, javac fails to raise an unchecked warning where it should. The test case shows the bug; and it also shows that an equally uncheckable cast, without a subtype introduced, does raise the warning.
It seems to appear to me that the author of the collections class may have used this technique thinking that since the returned object never operates on any object of its type argument type that it turns out to be safe to perform this cast. Unfortunately it must lead to a warning.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create some generic class.
2. Create a subclass with a given type argument type.
3. Create an instance of the subclass.
4. Cast the subclass to the superclass type with some other generic argument type.
The case will not raise a warning though it should.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The unchecked warning.
ACTUAL -
No warning.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
If the casted object does in fact contain some reference of a type not matching the type given in the cast expression then a runtime exception can occur.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
(Compile this class with the "-Xlint" option and see that no warnings are raised. Then run it and see a runtime exception due to an unchecked erroneous cast. Uncomment the optional code to see another path to attempting the same cast which does raise a warning.)
// A generic class:
public class TypedCastBug<T> {
// A parameterized subclass, typed with Object:
static class Child extends TypedCastBug<Object> { }
// ** This method performs an unchecked cast that javac
// erroneously does not issue a warning for:
static <U> TypedCastBug<U> create() {
Child child = new Child();
child.set(new Object());
return (TypedCastBug<U>) child;
}
// Run this to see a runtime exception caused through the cast in create():
public static void main(String[] args) {
TypedCastBug<Number> c = create();
Number n = c.get();
}
// Instance data and methods:
T t;
void set(T t) { this.t = t; }
T get() { return t; }
// An example of a similar API that does cause javac to raise a warning:
// static TypedCastBug<Object> willWarn = new TypedCastBug<Object>();
// static <U> TypedCastBug<U> raisesTheWarning() {
// return (TypedCastBug<U>) willWarn; // Effectively the same as above
// }
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Note that any cast to a parameterized type is not checkable:
(List<XXX>)
The actual argument type (XXX) is not known at runtime.
- duplicates
-
JDK-6558558 Missing "unchecked" diagnostic
- Closed
-
JDK-6558569 Missing unchecked warning
- Closed
-
JDK-6559179 Unchecked upcast not identified
- Closed
- relates to
-
JDK-6790039 overhaul cast-conversion (umbrella)
- Closed