12/23/2013 - 8:00 PM

JVM vs

JVM vs

Type erasure

  • Genetic
  • Reflection
  • Static method

In Java, it's impossible to get current class/type in static method. The C# code would be.

// C#
public static Type GetType() {
    return MethodBase.GetCurrentMethod().DeclaringType;
  • Performance

Primitive type aside object-oriented

// Java
ArrayList<int> list = new ArrayList<>(); // Compile-time error

In C#, all "primitive" type are actually aliases to ValueType class under System namespace.

See Java: int versus Integer and int vs Integer

Covariance and contravariance

Java doesn't support covariance and contravariance for generic types.

// Java
List<String> strings = new ArrayList<>();
List<Object> objects = strings; // Compile-time error
// C#
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;

Array is not collection

No property

// Java
public class Foo {
    int x = 0;
    public int getX() { return x; }
    public void setX(int x) { this.x = x; }
// C#
public class Foo {
    public int X { get; set; }  // Easy, simple, and flexible.

Access of some primitive type is not atomic

// Java
static double x = 1.0;
x = 2.0;    // Not thread-safe

See official tutorial.

Non-runtime exceptions need to be declared after method

Change of the method behavior will affect the interface of the class. It requires the caller to be recompiled in order to adapt the new interface. See official tutorial.

No event/delegate

No var keyword, which produces cleaner code and saves keystroke.

.NET provide extension method

// C#
class A {
    public int Value { get; set;}
    public A(int value) {
        Value = value;
static class Extensions {
    public static void Print(this A a) { // Extends A class with Print method.
        Console.WriteLine("Value: " + a.Value);

And magic happens

var a = new A(123);
a.Print();    // Prints "123".

Java lacks of native concurrency management except thread.

  • .NET provides Task Parallel Library which is very powerful and easy-to-use. Unlike most of non-blocking framework which requires you to chain your logic deeply. C# provides await/async syntax to make the code easier to read and write.

Java has no native support for clone.

In Java, protected classes/fields/methods are not really protected

Unlike C++ and C#, Java's protected access modifier acts a little bit unexpected, which also allows classes in the same packages to access it.

Comparison of the access modifiers in both languages:

internal protectedN/A

In Java, file system structure must reflect the packaging structure

  • Which make the code management crazy and inflexible. sometime the filename are too long for some programs to handle.

Java Date/Calendar library is a joke

  • Use Joda-time in Java to deal with time-related operations.

Wrong design about the super(base) constructor placement

// Java
public class Derived extend Base {
    public Derived() {
        int x = 0;  // Compile-time error
        super(); // This is enforced by compiler to be the first statement.

C# has a more clear definition for this:

// C#
public class Derived : Base {
    public Derived() : base() {}    // Clearer, no chance for error

The using statement v.s. automatic resource management

// Java
try (Db db = new Db()) {
// C#
using (var db = new Db()) {
  • In Java, the declaration of the close-able object must be inside the parentheses.
// Java
Db db;
try (db = new Db()) {}  // Compile-time error

It seems that Automatic Resource Management changes the variable scope.

ref and out keywords

Sometimes when you want a method to pass the parameters by references, ref and out come in handy. However, Java lacks of them. Java programmer needs to wrap the variable in an object in order to pass by reference.

// C#
class Program {
    public static void Foo(ref int x, out int y, int z)
        x = Int32.Parse(x.ToString()) + x;
        y = Int32.MaxValue;
        z = Int32.Parse(z.ToString()) + z;
    public static void Main()
        int x = 32, y, z = 32;
        Foo(ref x, out y, z);
        Console.WriteLine("x = " + x);  // 64
        Console.WriteLine("y = " + y);  // 2147483647 or Int32.MaxValue
        Console.WriteLine("z = " + z);  // Still 32

Different styles of generic method declaration

// Java
<T> T get(T x) {
    return x;
// C#
T Get<T>(T x) {
    return default(T);  // Returns the default value of generic class T.

Java lacks of operator and indexer overload

Java label vs C# label

  • In Java, program could break and continue a labeled loop.

  • In C#, program could goto a label.