Menu

C# And Java Differences: Runtime

April 9, 2013 - .NET, C#, Programming

I’ve already covered this topic from the perspective of why C# is better than Java, In my opinion. This time, I’ll go over the differences as even-handed as possible. This has come about primarily because I’ve been working extensively in Java, and find there are features that I like and dislike in both languages. Though I will admit I lean heavily towards C#.

First, how about a little history on them?

Java

Most, if not all, Languages and platforms have a varied and sometimes tumultuous history. The Java language and platform is definitely no exception. In it’s earliest incarnations, Oak, the purpose behind Java was to provide a platform and language to automate appliances. This is not really as far-fetched as it would seem, since most appliances do run some sort of software. If you pick a toaster off a shelf at random you have a good chance of getting something that runs some sort of executable code. The purpose was, presumably, to make this behaviour something that could be patched and changed more easily by end-users; much like how many car owners who are versed in technology will sometimes change the internal firmware to eke out better performance, one could see a person customizing their coffee maker or kettle for specific purposes.

The language, however, proved too useful for such a niche market, and eventually found it’s way onto the PC platform. It was initially met with some rather exorbinant and out of proportion enthusiasm, as Java was cited as the be all end all of all things on the web. Needless to say, that did not come to pass. Java- the language and technology- have now settled into being used for server-side development and the development of applications and games, instead. A purpose for which it is well suited, for the most part.

C#

There are some proponents- who not surprisingly are strongly biassed towards Java technologies- that claim that C# and .NET are a poor attempt by Microsoft to attempt to replicate Java. This is a rather ill-thought claim. While there is some interesting history behind C#, since it appeared relatively shortly after Sub Microsystems revoked Microsoft’s Java License, it’s very likely it was already in development anyway. Even if we go with that assumption and consider that C# is in fact Microsoft’s Java baby, it has still found itself in a very similar- but different- market.

Design Differences

One of my overriding dislikes of the Java language is mostly in the design strategy, which typically avoids the addition of language features if they can be misused. For this reason, Java does not have Operator overloading, Properties, and various similar features, under the guise that it’s easy to misuse them. In a similar vein, it lacks the ability for the programmer to create their own value types, while at the same time presenting somewhat confusing exposures for it’s own primitive types.

Java is a language designed essentially in tandem with it’s bytecode. Java source is compiled into Java Bytecode; this bytecode is an intermediate executable code that is run by a Java Virtual Machine; the Java Virtual Machine emulates a “stack-based” CPU.

C# is also designed in tandem with the CLR, it’s execution environment, but the CLR is designed with the capabilities of other languages in mind. For example, While Java uses every single feature of the Java Bytecode for Java features, C# does not actually exploit all features of the CLR and the IL bytecode that the language compiles to. What makes this interesting is that while all Java bytecode can be “decompiled” to some equivalent Java source, not all IL code can be decompiled to C#. For example, Visual Basic .NET uses a few features of the CLR that are not used in C#, such as Exception filters.

Generics

Generics are one feature that is implemented quite differently between each language. The Java approach is to make the feature something that is dealt with before the Virtual Machine runs it. What this essentially means is that, when compiling a generic class, the Java Compiler replaces all type parameters with their type restrictions (the Java docs call them “bounds”). If the type parameter is unrestricted/unbounded, then the compiler will use the Object type. The compiler will insert type casts where necessary to preserve type safety (which includes both code within the generic class as well as code that utilizes the generic class) and generate appropriate “bridge” methods between a generic base class and a class that extends from it.

C#- thanks to the CLR- has full-on support for Generic types. The ramifications for this go both ways. Whereas the Java method of Type Erasure allows your program to work successfully on older Virtual Machines as well as newer ones (because the VM is not changed) you lose out on the ability to use generics through reflection. C#, on the other hand, allows you to create a new Type based on a generic type and the types of it’s parameters, and then instantiate the applicable classes as desired. Reflection is extremely powerful in both Java and C#, but this particular ability can be very appealing for some designs. On the flip-side, however, in order to use Generics in C#, the code needs to be running on the Version 2 CLR; in fact if you compile for a later version of the CLR, the resulting compilation will not work on earlier versions. This is because the CLR development mantra is to work to add improvements to the system as a whole, while allowing legacy code to run without recompilation by allowing side by side installation.

One interesting way to compare the two platforms is with a direct demonstration and comparison of otherwise functionally equivalent segments of code. Now on e might think I would turn to the Java and C# implementations as part of my ongoing Anagrams Series, but since we will be looking at the IL and Bytecode of each, it might be ideal to go for brevity. I’ve settled on a simple program that uses a Generic structure to store 100 values, and then write them out. Here is the Java implementation:

Something of note is that we need to use List rather than List because generic type parameters must be class types. This is sort of a side-effect of the way Type Erasure was implemented, since it essentially inserts appropriate casts to the proper type when the Type parameter is used. the Integer type is a boxing class that is provided by the Java Class Library, and for which the compiler has special considerations for (like the other boxing classes). The disassembled Java bytecode from this is shown below. This is from the main method, and I stripped out the extra stuff about the methods and whatnot.

Edit: Fixed the markup issue. you would think the &ltpre&gt tag would prevent other tags from being identified within, but apparently WordPress still helpfully tries to auto-complete tags when you save a post…
Some take-aways from this. We can see Type Erasure in action starting at the first invokespecial line, which invokes the constructor. The constructor is of java.util.ArrayList. But this lacks any Generic context. As we can see in the future calls, many of the references to and from the List are cast to an Object when being passed and cast to an Integer when being retrieved. This shows Type Erasure in action.

Moving on to C#:

This one is a lot shorter than the Java version because I’ve used as many language and framework features as I thought I could get away with. To say the resulting IL dissassembly was verbose in comparison would be an understatement:

A lot of the verbosity here is due to the explicit referencing of various framework types. it’s also interesting that the resulting IL has an Exception Handler which is most likely attached through scope. That is, scoping braces in blocks will cause any declared variables within to be deconstructed as necessary. This doesn’t run measurably slower than the Java version. Fundamentally, while this IL looks longer (and a reasonable assumption to base on that would be that it’s slower) it’s also just a representation of the internal IL code. Additionally, the CLR has a very powerful JITter that will compile segments of code on the fly to Machine language, which is particularly helpful for looping constructs, or really any code that repeats more than once.

In order to better flesh out differences as I encounter them or learn enough about them, I’ve decided this will be something I shall repeat- a series, if you will. Expect more blog posts on the subject of C# and Java differences. If necessary consider this post a primer and look at their run-times.

Have something to say about this post? Comment!