Difference between JVM and CLR
Architecture of the CLR is remarkably similar to the architecture of the JVM. But there exits lot of differences too. It also bleeds into differences between Java and C# whose features often include compiler-level only features that the underlying VM is not cognisant of. Some of the differences between CLR and JVM are explained here.
Unsigned Data types
JVM doesn’t support unsigned arithmetic data types, however CLR supports both signed and unsigned data types and all applicable arithmetic operations on both signed and unsigned data types.
CLR supports namespaces to organise related classes, interfaces etc. However JVM doesn’t support any logical equivalent to CLR namespace.
Explicit Interface Implementations
CLR not only supports implicit interface implementation, but also supports explicit interface implementation. However JVM lacks explicit interface implementation.
The CLR allows user code to define new value types (structs), whereas the JVM provides a fixed collection of value types (byte, short, int, long, float, double, char, boolean) and only allows users to define new reference-types (classes).
Pass by Reference
CLR supports passing arguments to value by reference (implemented with the C#
ref keyword). However JVM supports only passing arguments by value
CLR supports closures (implemented as C# delegates), However JVM doesn’t support closures.
The CLR has coroutines (implemented with the C# ‘yield’ keyword). The JVM does not.
The CLR provides support for declaring and manipulating pointers. This is especially interesting because both the JVM and the CLR employ strict generational compacting garbage collector implementations as their memory-management strategy. Under ordinary circumstances, a strict compacting GC has a really hard time with pointers, because when you move a value from one memory location to another, all of the pointers (and pointers to pointers) become invalid. But the CLR provides a “pinning” mechanism so that developers can declare a block of code within which the CLR is not allowed to move certain pointers. It’s very convenient
One interesting difference is that the CLR includes instructions for creating generic types, and then for applying parametric specialisations to those types. So, at runtime, the CLR considers a List to be a completely different type from a List.
Under the covers, it uses the same MSIL for all reference-type specialisations (so a List uses the same implementation as a List
bytecode format (composed of MSIL instructions and metadata) has fewer instruction types than the JVM. In the JVM, every unique operation (add two int values, add two float values, etc) has its own unique instruction. In the CLR, all of the MSIL instructions are polymorphic (add two values) and the JIT compiler is responsible for determining the types of the operands and creating appropriate machine code. I don’t know which is the preferably strategy, though. Both have trade-offs. The HotSpot JIT compiler, for the JVM, can use a simpler code-generation mechanism (it doesn’t need to determine operand types, because they’re already encoded in the instruction), but that means it needs a more complex
bytecode format, with more instruction types.