Sunday, June 08, 2008

jSuneido - C++ Templates versus Java Generics

I'm currently working on porting Suneido's btree code from C++ to Java.

It's challenging because the C++ version makes heavy use of templates (plus a few other pointer type tricks).

If I look at the C++ code one way it seems really elegant, but if I look at it another way it seems really twisted.

The problem is that Java generics are very different from C++ templates. I know that people complain about Java generics, but just using the standard generic collection classes it seems fine. It's only when you try to write a more complex generic class that you start to see the reason for the complaints.

Java generics work by "type erasure". In C++ terms this would be like compiling all your templates down to a single void* version. This had the big advantage that it was backward compatible and didn't require any VM changes. (It also results in smaller compiled code.) The disadvantage is that you "lose" all the type information at run-time.

For example, class can't do new T() because T has been "erased" (to Object).

The way around it is to create new objects via an instance. This instance can be the class - Class - in which case you use newInstance from the reflection API. Or it can be a "factory" object. Unfortunately, this instance has to be passed in (since the whole problem is that generic classes can't instantiate parameter types)

This will all be old hat to experienced Java programmers. And it wouldn't be a big issue for me, except that I'm trying to port C++ templates that have no problem instantiating parameter types ...

No comments: