Differences between MSIL and Java bytecode?

First off let me say that I don’t think that the subtle differences between Java bytecode and MSIL is something that should bother a novice .NET developer. They both serve the same purpose of defining an abstract target machine which is a layer above the physical machine being used in the end.

MSIL and Java bytecode are very similar, in fact there is was a tool called Grasshopper which translates MSIL to Java bytecode, I was part of the development team for Grasshopper so I can share a bit of my (faded) knowledge.
Please note that I stopped working on this around when .NET framework 2.0 came out so some of these things may not be true any more (if so please leave a comment and I’ll correct it).

  • .NET allows user defined types that have value semantics as apposed to the regular reference semantics (struct).
  • .NET supports unsigned types, this makes the instruction set a bit richer.
  • Java includes the exception specification of methods in the bytecode. Although exception specification is usually only enforced by the compiler, it may be enforced by the JVM if a class loader other than the default one is used.
  • .NET generics are expressed in IL while Java generics only use type erasure.
  • .NET attributes have no equivalent in Java (is this still true?).
  • .NET enums are not much more than wrappers around integer types while Java enums are pretty much fully fledged classes (thanks to Internet Friend for commenting).
  • .NET has out and ref parameters.

There are other language differences but most of them are not expressed at the byte code level, for example, if memory serves, Java’s non-static inner classes (which do not exist in .NET) are not a bytecode feature, the compiler generates an additional argument to the inner class’s constructor and passes the outer object. The same is true for .NET lambda expressions.

Leave a Comment