Top 10 differences between Java and C#

My latest transition from Java to C# left me scratching my head and scrambling to find the differences.  Don’t get me wrong — they are very similar, but some key syntax and philosophical differences set these two languages apart.  Below are my top 10 differences that I wish someone told me before I pulled out yet more hair.

Gotcha #10 – Give me my standard output!
Gotcha #9 – Namespaces == Freedom
Gotcha #8 – What happened to super?
Gotcha #7 – Chaining constructors to a base constructor
Gotcha #6 – Dagnabit, how do I inherit?
Gotcha #5 – Why don’t constants remain constant?
Gotcha #4 – Where is ArrayList, Vector or Hashtable?
Gotcha #3 – Of Accessors and Mutators (Getters and Setters)
Gotcha #2 – I can’t override!?
And the #1 gotcha…

Gotcha #10 – Give me my standard output!

This may not seem like a big deal, but when I’m first getting my head in a language, I want to be able to debug.  With everything so new and shiny, I don’t want to hear about the debugger yet, I don’t care about the fancy message boxes, just tell me how to get something on standard output!

In C#, the code looks like this:

Console.WriteLine("your string here");

Gotcha #9 – Namespaces ==  Freedom

In Java, the package hierarchical structure mirrored the directory hierarchical structure.  This made sense to a degree, but then why didn’t Sun just auto-derive the package structure?  Anyway, Microsoft has freed us from this constraint.  The C# package structure is defined using namespaces (just like Java), but the namespaces do NOT have to reflect the directory structure.

Gotcha #8 – What happened to super?

Slight renaming of keywords drives me bonkers!  Substitute Java’s super keyword with base.

Gotcha #7 – Chaining constructors to a base constructor

In Java, I often created a set of constructors with differing parameters that all reference a common all-powerful constructor.  In other words, I created a set of overloaded constructors that basically just called a constructor that did the bulk of the work.  This is called constructor chaining and normally leads to easier to maintain code.  In Java, the this(…) statement is used to call the constructor.  In C#, this is done right up in the method signature.

public MyConstructor(int i) : this(i, -1)
{
    ...
}

public MyConstructor(int i, int j)
{
    ...
}

Gotcha #6 – Dagnabit, how do I inherit?

In Java, the keyword extends is used to inherit from a parent class, and the keyword implements is used to inherit an interface.  In C#, the distinction does not exist and it’s all done in the method signature.

public class MyClass : MyParentClass
{
    ...
}

Gotcha #5 – Why don’t constants remain constant?

Well of course they do!  Just not among different languages.  In Java, I normally defined global constants using public static final.  In C#, the static keyword does exist (final does not), but you can define constants like this:

public const MyConstant = 101;

When the constant needs to be initialized at run-time (for example in a constructor), use the readonly keyword instead of const.

Gotcha #4 – Where is ArrayList, Vector or Hashtable?

In Java, these guys were my staples.  Pre-built dynamic arrays and look-up tables decrease development time and makes my life a whole lot easier, but where are they in C#? C# has an ArrayList, but it doesn’t make use of generics. Instead, I like to use:

System.Collections.Generic.List<>

Unfortunately, List<> is not thread-safe (C#’s ArrayList and Java’s Vector are thread-safe). C# also has a Hashtable; the generic version is:

System.Collections.Generic.Dictionary<>

Gotcha #3 – Of Accessors and Mutators (Getters and Setters)

As long as methods exist in classes, accessors and mutators will exist.  However, C# largely replaces them with class properties. Instead of the traditional getSomeInteger() and setSomeInteger(), we use properties!

public class SomeClass
{
    int someInteger = 42;

    public int SomeInteger
    {
        get { return this.someInteger; }
        set { this.someInteger = value; }
    }

    public void Main(string[] args)
    {
        SomeClass c = new SomeClass();
        Console.WriteLine(c.SomeInteger);
        c.SomeInteger = 420;
    }
}

this.someInteger is a class variable, and value is the new integer.

Gotcha #2 – I can’t override!?

At this point, we’ve transcended the syntax differences and we’ve entered into more philosophical choices that the Microsoft team made. In Java, all methods are by default virtual and you can override them. In C#, all methods are non-virtual. To override a method in the parent class, make sure the method of the parent class is defined as virtual using the virtual keyword.

class MyParentClass
{
    public virtual void MyMethod() { ... }
}

In the child class, the method must use the override keyword.

class MyChildClass : MyParentClass
{
    public override void MyMethod() { ... }
}

And the #1 gotcha…

I remember when I first learned Java, and everyone was saying how Java made everything an object. How Java forced you to make classes for everything. This turns out to be partially true. It is necessary to make classes.  However, primitives are not objects. In C#, even what were considered primitives in Java are objects in C#.  Absolutely everything descends from System.Object.  This choice by the C# team allows for greater consistency and for such things as a cleaner implementation of automatic boxing/unboxing.

Tags: ,

22 Responses to “Top 10 differences between Java and C#”

  1. raveman Says:

    good read, i forgot most of this, what about generics in c#? do they have generic collections?

  2. Chad Campbell Says:

    This is a great list. Thanks for taking the time to post it.

  3. Jordan Says:

    I am wondering if perhaps you are not as experienced with C++ as you are with Java. A lot of your confusion (8, 7, 6, and 5) seems to stem from a Java-centric view of OO. Those four items make perfect sense from a C++ developers perspective. I think, although C# is very java-like in the way it works, it was meant to be C++-like in syntax. After all, it -is- C#, and not Java# :) .

  4. John Wood Says:

    As a (primarily) Java developer, I’ve also noticed that C# handles abstract classes that implement interfaces differently. In Java, an abstract class can implement an interface, and not provide implementations of all of the interface’s methods…since that class can never be constructed. It is the responsibility of the first concrete class that has that abstract class as an ancestor to implement all of the methods in the interface.

    C# on the other hand seems to require that the abstract class provide implementations for all of the methods on the interface. Even if that implementation is just a method signature.

    A good summary of this can be found at http://msdn.microsoft.com/en-us/library/ms173156.aspx, towards the bottom of the page.

    I’m still struggling to understand this, so if anybody can chime in with some clarification, I’d certainly appreciate it. :)

  5. Casper Bang Says:

    Good list, could perhaps use a bit of reasoning. I.e. namespaces exists such as to separate logical from physical organization. And non-virtual by default exists such that a new release of a base class does not clash with an existing method in a derived class, which would typically raise a link/verifier error (bad) or fail silently (worse).

    Also, there are all the differences revolving around having delegates/events, properties, reified generics, only non-checked exceptions and so forth but perhaps you will get to that. :)

  6. lowell Says:

    great list.. i work in objective-c so most of the code looks alien to me, but i remember a little java from school and i’ve played (however briefly) with c# in a couple of porting projects i ended up reassigning.

    i was, however, confused by #10. the std output isn’t that different between the two.. did you list it because you thought they’d be identical?

  7. Raymond Li Says:

    @Casper: I definitely appreciate the reasoning. Thanks for commenting!

    @Jordan: Great point! C# definitely derives a lot of syntax from C++. Although I’ve done a few smaller projects in C++, Java was definitely much fresher in my mind when I made a transition to C#.

  8. Elwin Luo Says:

    Great list!
    however, there are many C# important features java have not,
    sas
    Partial class, attribute, linq…

  9. malino01 Says:

    Just wanted to be sure u were aware that java has auto boxing/unboxing

  10. Raymond Li Says:

    @raveman: C# absolutely has generic collections. The namespace System.Collections.Generic (which includes the List<> and Dictionary<> classes I described in gotcha #4) should be a perfect fit for you.

    @John: This is a tough one. I think C#’s approach gives the programmer finer control, and I may make this the topic of another post.

    Update (9/28): Why does an abstract class need to implement interface methods?

    @lowell: Thanks for your comments! Regarding #10… yes, the Java equivalent is not much different. However, it is different enough that I needed to go poking around for the C# equivalent.

  11. Rasheed Says:

    Gotcha #3

    You can use a smaller syntax!

    public class SomeClass
    {

    public int SomeInteger
    {
    get;
    set;
    }

    public void Main(string[] args)
    {
    SomeClass c = new SomeClass();
    c.SomeInteger = 42;
    Console.WriteLine(c.SomeInteger);
    c.SomeInteger = 420;
    }
    }

    very useful!

    Hope it helps!

  12. Alex Says:

    I think the #1 difference is that C# doesn’t have checked exceptions. This is really a huge difference in day-to-day programming.

  13. Raymond Li Says:

    @malino01: Good catch! I changed the wording.

  14. Jingchen Says:

    generic in C# is like:
    public class MyClass where T : IMyInterface
    {
    }

    “where T : IMyInterface” tell the compiler the type of T must implements IMyInterface.
    u also can write “where T : class” to restrict T to be a class but not a struct. (struct is an light-weight class in C#)

  15. James Says:

    I agree with Alex. The exception handling is the biggest gotcha I found with C# which drives me crazy. I always feel like I’m throwing caution to the wind by not having SOME exception handling code being demanded by the compiler…

    On the subject of exceptions, C# and Java use different syntax to rethrow an exception… i.e. “throw;” vs “throw e;”.

  16. Guy Mac Says:

    One Error, Java’s ArrayList is not thread-safe, Vector is. Likewise with HashMap and Hashtable.

  17. Raymond Li Says:

    @Guy Mac: I can see how the original phrasing was confusing. I have changed it now. Thanks!

  18. Jared Says:

    Your #1 reason isn’t exactly true. Most types derive from Object, but there are exceptions. In C# there are reference types and value types. Types like int and bool are value types, whereas string is a reference type. Every class you create will be a reference type, whereas every struct you create will be a value type. This is important when you want to pass your objects as variables to a function and expect to be able to change values and have those changes after the function returns.

  19. Facebook Proxy Says:

    Hey, I just hopped over to your site via StumbleUpon. Not somthing I would normally read, but I liked your thoughts none the less. Thanks for making something worth reading.

  20. HoNgOuRu Says:

    Hi, ofcourse the ArrayList exists in c#

    just use the “using System.Collections” namepsace and you will be able to create ArrayList objects.

    I got a C# ArrayList post in by blog…

    and in “what happened to super” I believe that its the same in c# but called base

    this.base will call his super class.

  21. HoNgOuRu Says:

    I really like the design of your blog, mine stinks! LOL.
    I’m really new to blogging. Well Good Bye!

  22. Nagmani Singh Says:

    if u can make the difference column wise side by side it would be better to understand and how java is partial class even if we have wrapper class for implementing the primitives data types as a object??????

Leave a Reply