Saturday 7 March 2009

C# vs. Java. Slight differences

So, there is a one month passed since I became Java developer ...

Long before I've started to develop something essential on Java, this language invoked very contradicting thoughts in my mind.

In early 2005 when I have started my career in IT, I've started mainly with VB and C#, but there were dozen of languages I used as supplementary: Python, Perl, PHP, VBScript, JavaScript, batch, NAnt scripts and so on. Among them Java turned to be something prominent. Since it was and is lingua franca of IT industry I extensively used literature and articles written by Java developers and architects. Even if they were created to be used by exclusively Java teams. Thus besides Anders Hejlsberg and Andrew Troelsen not only people like Martin Fowler and Mike Cohn, but also Craig Larman and Bruce Eckel became my masterminds in IT branch. Later on when I grown up enough to make presentations how to do software and how not to do I was leaning to make code snippets either Java, still being quite distant from development in Java itself. But to be honest I was never felt uncomfortable talking to my colleagues in Java. Java and C# is in fact very close to each other, but there is one more peculiarity that makes couple Java-C# very similar to language couples: C# developers normally better understood Java then vice versa.

Now when I delved deeper into Java, I realize how many peculiarities in Java are actually different: Java has larger heritage from C++ then C#.

In practice you can try to evaluate this code in both languages:


String a = "Falafel";
String c = "fel";
String b = "Fala" + c;
System.out.println(a == b);


In C# you'll have to use System.Console.WriteLine instead of System.out.println
In Java you'll get false, while in C# you'll get true. Why? Simply because Java compares addresses of a and b, while .Net compares content. You should use equals (before 1.6) and StringUtils (since 1.6) in Java to compare strings correctly.

How about casting? Have you ever tried evaluate this expression

(int)(char)(byte)-1

Experienced Java developers will answer: (byte)-1 will cause overflow, so you might expect something like 65535 on the very end. C# gets obviously the same answer, but by default C# compiler refrains to compile such a mess. You'll be kindly asked to use unchecked option on your own risk:

unchecked
{
    int i = (int)(char)(byte)-1
}


Working with numbers is very messy in Java (I will keep using references whenever I worked with arithmetic operations
Hex number 0xfa1afe11 will output positive result in C#, but negative in Java. The reason is that hex number with leading 1 treat as negative.
Floats can also challenge you: Java expression

System.out.println(2 - 1.1);

outputs 0.8999999999999999
while in C#

Console.WriteLine(2 - 1.1);

gets 0.9

NB: I must admit, that in .Net trouble with floating point operations are not finally resolved (MathLab and Maple in any case do them better)

Java has special class BigDecimal to perform operations with additional precision or value, but you might be careful using them either. Don't you know what is the difference between two following expressions in Java

BigDecimal dec1 = new BigDecimal(.1);
BigDecimal dec2 = new BigDecimal(".1");

Can't you guess?
Oh, you might be surprised that first one will output huge ugly number

0.1000000000000000055511151231257827021181583404541015625

Gurus highly recommend to use constructor BigDecimal(String) and not convert primitives to BigDecimal directly

Expressions like i = i + k; and i += k; are not equivalent in Java, although many Java developers think they are.

In any case my way in Java has just begun and it will take couples month until I will be able to cause another overproduction crisis in IT ...