I do think, however, that the JVM is much more advanced than the CLR, and really the only one of the two that is truly cross platform and open.
As for cross-platform, well that's not a goal of the CLR so the JVM wins de-facto.
I've also seen examples of the JVM running well on extremely large boxes, where as I have not seen it with the CLR.
Templates in C++ or the generic types from Haskel enable parametric polymorphism which is a lot more elegant for certain problems than subtype-polymorphism (i.e. OOP).
Java's generics is only a hack to make it look as though some piece of code that's using subtype-polymorphism is parametric ... but it only saves you explicit type-casts, which are also useless.
dotNet's generics are different ... while sharing the same limitations (i.e. no late binding and not implicit interfaces), because the types are available at runtime the runtime dispatches being made aren't just hacks and you can use the reflection mechanism to workaround many of the problems associated.
I am rewriting a C# app in Java right now and I'm being forced into extremely awful hacks to prevent memory consumption from exploding. To illustrate how bad the situation is let me tell you that I'm seriously thinking about rewriting everything in C++ :-)
T obj;
obj = getObjFromSomewhere();
log(T.class);
This type of operation is most useful if writing framework type of some sort. I've come across it when trying to write a generic JPA base DAO type of class.http://www.scala-blogs.org/2008/10/manifests-reified-types.h...
It's improved a bit in 2.8 - in porting some code I discovered a nice little hack that lets you declare your variance like this:
[A <: SomeBaseClass <: Manifest]
Which tells the compiler in an oh so gentle manner to reify for you.
But my first reaction on headline before reading the article was "Ugh. I'm sorry". (I will read it in a second, I felt this obdurate urge to rant BEFORE I read it).
I coded in Java for work (After being hired to do Java) for years, then went over to Python, and worked with some C# for about a year. Now I'm back working with Java, and Scala (for which I have lots of love - it has a lot of what I love about Python but in many cases better).
There are little things in C# that just really give it an edge over Java. Among other things relating to Generics (Which are awful to begin with in that the JVM currently erases type information at compile time [Scala has a few clever hacks to get around it]) - as I understand it, C#/CLR automatically generates multiple specialized paths for all possible primitive types with generic collections.
And being a fan of closures, anonymous functions, etc. Java is just painful. C# has these, and more.
Now Off to read the article :)