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!

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.

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

public MyConstructor(int i) : this(i, -1)

public MyConstructor(int i, int j)

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:


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:


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();
        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.

About the Author

Ray Li

Ray is a software engineer and data enthusiast who has been blogging for over a decade. He loves to learn, teach and grow. You’ll usually find him wrangling data, programming and lifehacking.

Comments 24

  1. 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# 🙂 .

  2. 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. 🙂

  3. 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. 🙂

  4. 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?

  5. @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#.

  6. @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.

  7. Gotcha #3

    You can use a smaller syntax!

    public class SomeClass

    public int SomeInteger

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

    very useful!

    Hope it helps!

  8. 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#)

  9. 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;”.

  10. 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.

  11. 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.

  12. 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.

  13. 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??????

  14. Pingback: Top 10 differences between Java and C# | rayli.net | Power to Build

Leave a Reply

Your email address will not be published. Required fields are marked *

eight + 19 =