-
The Call of ChrismathuluR.J. LorimerFri, Nov 7 2008 @ 2:38 pm
-
Getting True Java Classes in JRubyR.J. LorimerThu, Sep 25 2008 @ 6:41 pm
-
JRuby 1.1.4 ReleasedR.J. LorimerFri, Aug 29 2008 @ 5:41 am
-
My XBoxR.J. LorimerMon, Aug 25 2008 @ 3:22 am
-
Why So Serious?R.J. LorimerSat, Aug 23 2008 @ 5:25 am
Reminder of Type Erasure Problems
I always hate when I’m reminded why I don’t like some technology. Today I was working with Java 5 and specifically a pre-Java 5 xml_rpc API similar to Apache XML-RPC. I made some incorrect assumptions about the return value of a particular rpc call. I was confident that it returned an array of strings (which is translated into a list of strings in Java) - but in fact it returns an array of structs (which is translated into a list of maps).
Before you think I’m a total idiot, this is relatively easy to have happen with XML-RPC because the return type is dependent on the specification of the XML-RPC call. Anyway, as a consequence, my code looked like this:
List<String> names = (List<String>)rpcClient.execute("my.method"); // A bunch of code here. // ... for(String s : names) { System.out.println(s); }
This is a much simpler adaptation than the reality, but this should cover the point. Of course, this code is totally incorrect. Unfortunately, all the compiler can tell me is that casting it as a List<String> is not safe. This is problem 1 - usually developers know what a collection has, so the compiler warning about this is typically annoying rather than helpful, and causes the error to lose significance (you will ignore it).
So now, I’ve done something to tell the compiler I’m smarter than it (added a @SuppressWarnings annotation) - only, this time I’m incorrect in my assumption.
Now, if I were wrong in my assumption in a pre-Java 5 world, I would have a list somewhere I tried to pull a String out of, and I’d get a ClassCastException.
While that’s what’s going to happen in my code above, it does so in a much more insidious manner. Case in point, if I have code like this:
@SuppressWarnings("unchecked") public List<String> methodA() { List<String> names = (List<String>)rpcClient.execute("my.method"); } public void methodB() { for(String s : methodA()) { s.substring(...); } }
Now, methodB has gotten what the compiler has said in a ‘type safe’ fashion is a list of strings, however it’s not. Sadly, this effectively means that we have ‘laundered’ a bunch of maps as strings. Doh!
