[e-lang] Type safety of Java generics
David Hopwood
david.hopwood at industrial-designers.co.uk
Tue May 29 16:07:35 EDT 2007
Constantine Plotnikov wrote:
> The reflection behavior is not unlike one of the compiler. The
> compiler error could be very easily stripped down as well. So
> reflection have the same safety guarantees as static type checking
> (broken ones).
>
> import java.util.ArrayList;
>
> public class UnsafeGenerics2 {
> @SuppressWarnings("unchecked")
> public static void main(String[] args) {
> // After type erasure, this is really an ArrayList of Object.
> ArrayList<String> a = new ArrayList<String>();
> // two lines below could happen when object is got from
> // HTTP session for example or used in legacy code.
> ArrayList<Integer> b = (ArrayList<Integer>)(Object)a;
> b.add(42);
> // This doesn't provoke a warning, but fails with a
> // ClassCastException at run-time.
> String s = a.get(0); // line 32
> }
> }
>
> So situation normal, all is broken as expected.
'Doctor, it hurts when I use @SuppressWarnings.' ;-)
Without @SuppressWarnings("unchecked"), this is what you get:
>javac UnsafeGenerics2.java
Note: UnsafeGenerics2.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
>javac -Xlint:unchecked UnsafeGenerics2.java
UnsafeGenerics2.java:10: warning: [unchecked] unchecked cast
found : java.lang.Object
required: java.util.ArrayList<java.lang.Integer>
ArrayList<Integer> b = (ArrayList<Integer>)(Object)a;
^
1 warning
I think this is perfectly reasonable. It's claims such as this one
by Sun that I object to:
<http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5105887>
# Generics are supposed to be statically type safe. However, in order
# to interface with old code and to allow programs which cannot be
# expressed type safely in the current language, we sometimes allow
# unsafe expressions but give mandatory warnings (they are required by
# the language specification). This means that we can give a type
# safety guarantee:
#
# "if your entire application has been compiled without unchecked
# warnings using javac -source 1.5, it is type safe."
There is no such guarantee. (Mutable covariant arrays are another reason
why not, but at least the fact that array mutation can fail at runtime
is well-known by Java programmers; the interactions between generics and
reflection are not.)
--
David Hopwood <david.hopwood at industrial-designers.co.uk>
More information about the e-lang
mailing list