Ok thanks Nic, that's interesting, I stand corrected on erasure, seems
it's not entirely true.
Any idea how we can enable runtime type checks for Generics?
So far we can get the type information, I know it's preserved in
bytecode from my experience with ASM and adding Generics support to
classdep, however, how does it stop me from setting the field reference
to another Collection, containing Integers, at runtime, then returning
it to the space?
Even with James' proposed javaspace method, which will work, the client
typecast is unchecked, it relies on the javaspace implementation to
return the correct type, which means you must trust the javaspace
implementation.
This places a significant burden on the service implementor.
What about Generics in other Service API?
I use Generics for it's added type safety, but type safety doesn't
extend to distributed code, since it is a compiler check (hint: I'd love
to be pointed to a runtime type checker for Generics) I'd understand
the attraction of using Generic's if it was the case, but I'm failing to
understand the relevance of Generic's without type safety, could someone
please explain it for me?
Or are we working on a tool to add type safety for Generic's to
distributed code?
Sorry, the direction so far just appears to be, add Generics to
distributed code, without type safety checks, it seems type checks might
interfere with performance or something.
Regards,
Peter.
Niclas Hedhman wrote:
On Sat, Dec 18, 2010 at 4:11 PM, Peter <[email protected]> wrote:
if you have a field in an Entry declared:
public Collection<String> names;
In bytecode, because of erasure, its type is Collection, this means I can
take from the javaspace and set the field to contain a Collection that
doesn't contain String's and the next time your code accesses it, a
ClassCastException will occur.
That is not correct. For fields, method return values and parameters,
the Type is preserved (ParameterizedType it is called). So for the
above example, do
Type[] types = names.getClass().getGenericInterfaces();
or something like this for the declaration itself
Field field = Main.class.getDeclaredField( "names" );
field.setAccessible( true );
Type type = field.getGenericType();
In fact, quite a lot of the things that people think are 'erased' are
actually not.
For instance, in a declaration like;
public interface Abc<K,V>
you can even retrieve the variable names of 'K' and 'V' respectively
(those Type are called TypeVariable).
Say what you want about Sun's compromises in the generics system, but
it is far from "just compiler checks".
In my project Qi4j (http://www.qi4j.org), we use this extensively to
do sweet things like;
Property<String> fullname(); // in an interface
to declare a property instead of getter-setter-mania...
Now, I am not saying that any of this should be deployed into River at
all, just that more things are possible than you might think.
Also Note; There are some small bugs in Sun's JDK1.5 generics
compiler, where some corner cases are handled incorrectly. The ones
that we have found are fixed in 1.6.
Cheers