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 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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…