Java vs C# – Part 3

Introduction

This is the third in a series of posts about the similarities and differences between C# (and .NET, to some extent) and Java. You can find the first one here and the second one here.

Again, with this I do not intent to demonstrate that one is superior to the other – totally – as I really like both platforms, even though I work mostly with C# and .NET. This is merely an exercise to show these differences and maybe it can be useful to someone who is learning one or the other. If you find something that you think is wrong, please let me know!

Keyword Usage

In Java, it is not possible to use reserved words, or keywords, such as class, public, etc, as variables, parameters or field names. In C# you can if you prefix it with @:. For example:

var @class = “My Class”;

Object Class

The Object class is the root of both type hierarchies in both Java and .NET. The two are pretty similar, with some remarkable exceptions. All of the following have exactly identical behavior:

Java .NET
clone MemberwiseClone
getClass GetType
equals Equals
hashCode GetHashCode
finalize Finalize
toString ToString

.NET does not offer methods corresponding to notify, notifyAll or wait. On the other hand, Java does not offer a method like ReferenceEquals.

Tuples

Recent versions of C# lets us return tuples, which are sets of values combined together ad hoc, but not inside a type definition. For example, should you wish to return a coordinate from a method, you could do this:

(double x, double y) GetCoordinates()

{

double x = …;

double y = …;

return (x, y);

}

It is also possible to “deconstruct” a class into a tuple, by providing a proper Deconstruct method:

public class Coordinate

{

public void Deconstruct(out double x, out double y)

{

x = …;

y = …;

}

}

Coordinate coord = …;

(double x, double y) = coord;

You can have as many Deconstruct methods you like, provided their signatures are different. For now, at least, Java is still lacking this functionality.

nameof

C# lets us use the nameof keyword to obtain a strongly-typed name of a class, method, property, field or parameter. It is very useful because it is refactor-friendly: should you change the name of the target, you also change the value that is being assigned. An example:

var className = nameof(MyClass); //”MyClass”

var fieldName = nameof(MyClass.MyField); //”MyField”

Mind you, only the “final” piece is returned, for example, if you use nameof with a fully qualified type name, you’ll only get the type name.

Friend Assemblies

As you know, internal classes and their methods are not available outside the current assembly/namespace. In C#/.NET, however, we can make these internals available to other assemblies by applying the InternalsVisibleToAttribute attribute to the assembly that we want to make available. These are called friend assemblies. For example:

[assembly:InternalsVisibleTo(“My.Assembly”)]

Async/Await

C# 5 introduced a new asynchronous programming model around the async and await keywords. I won’t go into the details of it but essentially it simplifies asynchronous programming a lot, preventing the usage of a lot of boilerplate code. It goes like this:

async Task<int> Compute(int a, int b) { … }

var result = await Compute(1, 2);

Import Methods

In C# we can import public static methods from public classes, which means, we can use them without prefacing them with the name of the class. The syntax is like this:

using static System.Environment;

and the usage:

var path = GetEnvironmentVariable(“PATH”);

Local Functions

.NET allows us to define local functions, that is, functions that exist only in the scope of methods. They are similar to lambda functions, with some remarkable differences, among which:

  • They can have attributes applied to its parameters
  • They can have ref, out and other kind of parameters
  • They can be asynchronous

An example:

void SomeMethod()

{

int sum(int a, int b) => a + b;

var x = sum(1, 2);

}

The closest that Java offers is anonymous classes, which are actually pretty cool, IMO.

Asserts

Java offers the assert keyword as part of the language, this has no equivalent in .NET. An assert evaluates a Boolean condition which, if not found to be true, throws an error:

assert speed < SPEED_OF_LIGHT;

Forgot to say, assertions can be disabled, which means, they are turned into no-ops.

Next Steps

I still have a couple of things to talk about, so be prepared for a future post!

As always, do let me know if you think I got anything wrong or you wish me to clarify something.

Java Flaws

One thing I didn’t talk about in my Java vs C# series (by the way, more to come soon) was some things that I think Java got wrong.

One of these things has to do with serialization. Java offers the Serializable interface, which is analogous to the [Serializable] attribute in the .NET world: both state that a class can be safely serialized (whatever that means). Then, Java has the transient keyword, used for marking a field as non-serializable! See my point? One – the interface – is an API, the other is a built-in language construct! .NET is more coherent, in that it has a [NonSerialized] attribute for this purpose.

Another one is method overriding. In Java, all methods are virtual by default, unless marked as final. Then, there is an annotation, @Override, that is now mandatory (since the introduction of annotations in Java) in overridden methods. Again, mixing APIs with language constructs.

The last one I want to talk about is default and static methods in interfaces. For those who don’t know, this means the possibility to define methods with their implementation in interfaces, something that should make all OOP lovers roll their eyes! I guess this was Java’s response to extension methods in .NET, but, again, it is something that I think .NET got right.

Java vs C# – Part 2

Introduction

This is part two of a series of posts on Java and C#. You can read the first part, on structure, here. This time, we are going to talk about a lot of things that weren’t covered before, and leave some stuff for future posts! Smile

Object and Collection Initialization

C# offers an interesting syntax for initializing instance properties at the same time a variable is declared, which can be combined with parameterized constructors:

MyClass c = new MyClass("constructor argument") { OneProperty = 1, AnotherProperty = "two" };

It also offers a syntax for defining the values of a collection upon declaration:

List<string> list = new List<string>{ "A", "B", "C" };

Dictionary<int, string> dictionary = new Dictionary<int, string>{ { 0, "A" }, { 1, "B" } };

Any class with an instance Add method can use this syntax, because it’s this method that the compiler calls behind the scene. Inside the { }, we need to pass as many elements as the Add method takes, and of the same type.

Casts

In Java, we only have one kind of cast between types:

Object o = ...;

String s = (String) o;

But in C#, we have two: the same as in Java, plus a “dynamic”, that returns null if the types are not compatible:

Object o = 1;

String s = o as String; //s is null

The as operator can only be used with reference types (classes and interfaces) and nullable types (like int ?). It does not automatically use conversion operators (see below).

In C# there’s also something related, the null coalescing operator. Basically, it allows this syntax for initializing a variable to some value only if it is null:

Object o1 = null;

Object o2 = new MyClass();

Object o3 = o1 ?? o2; //short for: o1 == null ? o3 : o1

Methods

Undefined Number of Parameters

Both Java and C# support methods with an undefined number of parameters. The syntax is slightly different, in C# being:

public void Print(params String [] args)

{

}

An in Java:

public void print(String... args)

{

}

Default Parameter Values

C# allows setting default parameter values. The default values can only be:

  • null;
  • Literals (“string”, 1, false, etc);
  • Enumerated values (MyEnum.Value);
  • Constant or read-only fields (MyClass. SomeField).
public void SayHello(String to = "me")

{

}

A method can have any number of parameters with default values, but these parameters need to come at the end, after any other parameters without default values. Java does not offer default parameter values, we have to use method overloading for that.

Changing Parameter Order

C#, unlike Java, also allows passing parameters in any order, by name, which is very useful when we have methods with a lot of parameters, and we don’t want to remember their exact order:

public void DoSomething(int a, string b)

{

}


DoSomething(b: "a string value", a: 10);

Passing Parameters by Reference

C# has two ways to pass parameters:

  • By value, the default, which is a pointer for reference types – classes and interfaces – and the actual value for value types – enumerations, structures;
  • By reference: the actual address of the variable is passed, similar to ** or & in C++.

Passing parameter values by reference can be done in one of two ways:

  • Forcing the parameter to have a value set;
  • Not forcing the parameter to have a value set.

One example that forces assignment uses the out keyword:

public void Execute(out int result)

{

    result = 0;

}

And if no assignment is required, we use ref instead:

public void Swap(ref int a, ref int b)

{

    int c = a;

    a = b;

    b = c;

}

Both out and ref are functionally equivalent, but out enforces a compile-time constraint that the parameter has a value set. Passing values by reference is particularly useful in the case of structures, because, since they are not passed by pointer, they need to be copied byte by byte, which can take some time, and they might also be boxed if the method argument is of a reference type; passing structures by reference only sends the address of the local variable.

By comparison, Java always passes parameters by value, meaning, basic types pass their actual bytes and the others are passed as pointers to the original variable.

Extension Methods

C# offers the concept of extension methods. An extension method appears to be part of some type, as an instance method of that type, but it doesn’t break encapsulation, because it really isn’t part of it, and it doesn’t have access to the type’s internals.

Extension methods are defined as static methods in static classes with a this parameter of the target type:

namespace Extensions

{

    public static class StringExtensions

    {

        public static String Revert(this String s)

        {

            //...

        }

    }

    }

We call an extension method just as we call a regular method, provided that the class that defines it is in context, either by being in the same namespace as the calling method’s class, or by having its namespace imported.

using Extensions;//this is where the StringExtensions class lives


//...


String text = "abcd";

String reverted = text.Revert();

Java has virtual extension methods, also called default methods, which provide a default implementation of a method in an interface, which is then inherited (and can be overridden) by classes implementing the interface. This is the building block for the Stream API introduced recently. I talked about default methods on the first part of this series, but here’s an example.

public interface MyInterface

{

    default void doSomething()

    {

        //do something

    }

}

Default methods are always public, so there’s no need to use the public qualifier.

Static Interface Methods

Java also allows defining static methods, with implementation, in interfaces:

public interface MyInterface

{

    static void doSomethingElse()

    {

        //does something else

    }

}

Like default methods, static interface methods are always public.

C# doesn’t have any way to add statics or code to interfaces.

Synchronized Methods

Both languages allow a method, static or instance, to be declared as synchronized, meaning, it will lock the object on which it is being called (or the class, if it is a static method). The Java syntax is:

public synchronized void myMethod()

{

    //I am synchronized

}

While the C# one use the MethodImplAttribute attribute:

[MethodImpl(MethodImplOptions.Synchronized)]

public void MyMethod()

{

    //I am synchronized

}

The syntax for acquiring a lock on an object is identical, but Java uses the synchronized keyword:

synchronized (this.someLock)

{

    //...

}

And C#, lock:

lock (this.someLock)

{

    //...

}

Inline Methods

In C#, it is possible to instruct the compiler to try to inline certain methods, through the MethodImplAttribute attribute:

public class Something

{

    [MethodImpl(MethodImplOptions.AggressiveInlining)]

    public void ShouldBeMadeInline()

    {

    }

}

The actual decision, however, is up to the compiler. Java does not allow this.

Operator Overloading

Overloadable Operators

In C#, most operators (arithmetic, comparison, bitwise) can be overloaded for a class, similarly to C++. This means that C# allows them to be redefined, so as to implement a more friendly syntax, or just change the default one:

public static bool operator == (MyClass c1, MyClass c2)

{

    return c1.MyProperty == c2.MyProperty;

}

In this example, I am changing the default == operator, which just does a reference comparison, to a value comparison, where the actual contents of the class are compared. If we change ==, we also need to change !=:

public static bool operator != (MyClass c1, MyClass c2)

{

    return !c1 == c2;

}

Some of the basic operators (+=, for example), cannot be defined explicitly, but can be defined from others (+):

public static MyClass operator + (MyClass c1, MyClass c2)

{

    return new MyClass(c1.MyProperty + c2.MyProperty);

}

It is also possible to compare unrelated classes, but the declaring class must appear as one of the arguments:

public static bool operator == (MyClass c, String s)

{

    return c.MyProperty == s;

}

The argument order defines if the operator is to be applied, for example, the previous code applies to:

MyClass c = new MyClass();

bool areEqual = c == "some string";

But not to:

MyClass c = new MyClass();

bool areEqual = "some string" == c;

We can, however, add two times the same overloadable operator with the arguments switched, so that they can be called interchangeably. The String class overrides the == operator, so as to always do comparisons by value.

The number of arguments is defined by the operator, there are unary and binary operators, and the types they return cannot be changed. For example, operator == always expects two arguments of any kind but has to return a bool.

Type Conversions

C# also features a special kind of operator: type conversion. Actually, there are two, for implicit and explicit conversions. Implicit conversions do not need an explicit cast:

public static implicit operator string (MyClass c)

{

    return c.MyProperty; //MyProperty is of type string

}


MyClass c = new MyClass();

string s = c;

Whereas explicit ones do:

public static explicit operator int (MyClass c)

{

    return int.Parse(c.Property); //MyProperty is of type string

}


MyClass c = new MyClass();

int s = (int) c;

All operators need to be public and static.

Attributes

Attributes are static metadata that can be added to types, packages, parameters, members, variables and assemblies (in C#). Some attributes have meaning to the compiler, and in C#, they can even be used as an Aspect-Oriented Programming (AOP) mechanism, because some system attributes are evaluated at runtime.

Java offers the following out of the box attributes (called annotations in Java):

  • @FunctionalInterface: declares an interface as a functional interface (an interface with a single method);
  • @Override: informs the compiler that the method to which it is applied is an override of a method with the same name and signature declared in a base class;
  • @Deprecated: marks the method as deprecated, which issues a compile-time warning;
  • @SafeVarargs: suppresses warnings related to the (mis)use of varargs (undefined number of parameters);
  • @SuppressWarnings: tells the compiler to suppress certain warnings, passed as parameters.

There are also meta-annotations, annotations that apply to other annotations:

  • @Retention: how is the annotation kept after compilation (SOURCE: only at source level, stripped at compilation, CLASS: kept at compile time, but ignored by the Java VM, RUNTIME: kept after compilation and considered by the JVM);
  • @Documented: when the annotation is applied, some elements should be documented with JavaDocs;
  • @Target: the single target of an annotation (ANNOTATION_TYPE: other annotations, CONSTRUCTOR: constructors only, FIELD: fields, LOCAL_VARIABLE: local variables inside methods, METHOD: methods, PACKAGE: packages, PARAMETER: method parameters or TYPE: any elements of classes);
  • @Inherited: the annotation can be inherited from the type’s base class;
  • @Repeatable: the annotation can be applied several times.

As you can see, an annotation starts with a @ and must be defined as an interface using a special syntax:

@Target(value=CLASS)

public @interface MyAnnotation

{

    String name() default "";

    int number();    //required since a default was not supplied

}

Annotation methods can only return basic types, enumerations and arrays of them, and cannot take parameters.

The application of the MyAnnotation annotation can be:

@MyAnnotation(number = 10) //uses default value for name

public class MyClass

{

}

In C#, attributes are not totally different, but there are some differences:

  • An attribute must inherit from the Attribute class, and, by convention, should have the Attribute suffix;
  • When applied, we can leave out the Attribute suffix;
  • Attribute’s members can only be of basic types, enumerations, or arrays of them;
  • Required attribute properties should be passed in the attribute’s constructor.

There are lots of attributes included in the .NET, so it is not practical to cover them all. I leave just some examples:

By applying an AttributeUsageAttribute, we can specify:

  • AllowMultiple: if there can be many occurrences of this attribute, in the same element;
  • Inherited: if the attribute’s presence and values is inherited in descending classes;
  • ValidOn: the elements to which the attribute can be applied (All, Assembly, Class, Constructor, Delegate, Enum, Event, Field, GenericParameter, Interface, Method, Module, Parameter, Property, ReturnValue, Struct).

Here’s an example of a C# attribute:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = true, AllowMultiple = false)]

public class MyAttribute : Attribute

{

    public MyAttribute(String required)

    {

        this.Required = required;

    }


    public String Required { get; private set; }


    public Int32 Optional { get; set; }

}

And its usage, notice that we leave out the Attribute suffix and the declaration syntax:

[My("name", Optional = 10)]

public struct MyStruct

{

    //...

}

Exceptions

Throwable Types

In .NET, any type can be thrown as an exception, but C# limits this to instances of the Exception class, or one derived from it.

In Java, we can only throw classes that implement the Throwable interface. The most common example of one such class is Exception.

Checked Exceptions

In Java, methods in classes, enumerations and interfaces must declare any exceptions that they may throw, except those inheriting from RuntimeException; these are considered special, in that they can be thrown at unforeseen situations – a division by zero, a null pointer access, etc. The syntax is for declaring the “expectable” exceptions is:

public void myMethod() throws MyException

{

}

Calling any method that declares that it may throw an exception requires that the calling code be wrapped in a try…catch block, where all checked exception types must be explicitly handled, or, of course, a superclass of them (catch is polymorphic):

try

{

    myMethod();

}

catch (MyException ex)

{

}

In both languages, more specific exception classes need to be catched first, that is, if you want to catch an Exception and a MyException that inherits from Exception, the catch block for MyException must be the first. C# allows you to omit either the class variable or even the class, if it doesn’t matter:

try

{

    //...

}

catch(MyException)

{

    //no need to refer to the exception instance

    throw;  //no argument required

}

catch

{

    //all other exception types

}

Rethrowing Exceptions

In Java as in C#, we can rethrow an exception caught in a catch clause:

try

{

    //...

}

catch (Exception ex)

{

    throw ex;

}

However, if we do it like this in C#, we lose the stack trace prior to the method issuing the throw. If we don’t want that, the alternative syntax is:

try

{

    //...

}

catch (Exception ex)

{

    throw;

}

Notice that if we don’t pass an argument to throw, it will rethrow the current exception – of course, this only works inside a catch clause.

Iterations

In C# and in Java we can iterate through the elements of a collection using either iterators or a specific syntax, which for C# is:

foreach (String item in list)

{

    //...

}

And for Java:

for (String arg : args)

{

    //...

}

In C#, any collection that has a method GetEnumerator returning an IEnumerator can benefit of this syntax, normally, all collections inheriting from IEnumerable (non-generic) or IEnumerable<T>. Java has a similar requirement, but the method needs to be called iterator and the required interface is Iterator<T>, which is implemented by most collections.

Returning Enumerables

In C#, if we want to return enumerations of values from a method, we normally prototype the method as returning IEnumerable<T>. If we do, we have a simplified syntax for returning individual values from it:

public IEnumerable<String> GetPhrases()

{

    var count = 0;


    for (var s in listOfStrings)

    {

        if (++count == 0)

        {

            yield break;    //break loop

        }


        yield return s;    //return one value, but continue loop

    }

}

Lambda Functions

Lambda functions in C# are built upon delegates and extension methods. A lambda is just syntactic sugar for calling methods – which can be defined inline, as anonymous ones -, and are most useful in collections processing:

List<MyClass> untidyCollection = ...;

List<MyClass> sortedAndFilteredCollection = untidyCollection.Where(c => c.MyProperty > 100).OrderBy(c => c.MyProperty).ToList();

In this example, Where and OrderBy are lambda functions defined over the IEnumerable<T> interface, which is implemented by List<T>. The types of the lambda variables can be omitted. This would be the same as:

class MyClassComparer : IComparer<MyClass>

{

    public Int32 Compare(MyClass c1, MyClass c2)

    {

        return c1.MyProperty.Compare(c2.MyProperty);

    }

}


List<MyClass> FilterCollection(List<MyClass> source, Int32 value)

{

    List<MyClass> target = new List<MyClass>();


    foreach (MyClass c in source)

    {

        if (c.MyProperty > value)

        {

            target.Add(c);

        }

    }


    return target;

}


List<MyClass> SortCollection(List<MyClass> source)

{

    List<MyClass> target = new List<MyClass>(source);

    target.Sort(new MyClassComparer());

    return target;

}


List<MyClass> untidyCollection = ...;

List<MyClass> sortedAndFilteredCollection = SortCollection(FilterCollection(untidyCollection));

Uuuf… see the gain?

A lambda can have several parameters:

Func<MyClass, Int32, MyClass> multiplicationTransformation = (c, multiplier) => new MyClass(c.MyProperty * multiplier);

MyClass source = ...;

MyClass target = multiplicationTransformation(source, 10);

In Java, things are very different. First, a lambda function can only be used over a functional interface, that is, an interface implementation with a single method. A method call that takes as a single parameter a class that implements this functional interface can be made a lambda function:

interface Operation

{

    default int operate(int a, int b);

}


class Calculator

{

    int doOperation(Operation op, int a, int b)

    {

        return op.operate(a, b);

    }

}


Calculator calc = new Calculator();

Operation sumOperation = (int x, int y) -> x + y;

calculator.doOperation(sumOperation, 1, 2);

Also comparison:

List<MyClass> unsortedCollection = ...;

List<MyClass> sortedCollection = Collections.sort(unsortedCollection, (MyClass c1, MyClass c2) -> c1.getMyProperty().compareTo(c2.getMyProperty()));

And finally, action listeners:

JButton button = ...;

button.addActionListener(evt -> System.out.println("Button clicked"));

Expression Trees

Related, but even more interesting than lambda expressions, are expression trees. These can be defined using the same syntax as lambda expressions:

List<MyClass> untidyCollection = ...;

IQueryable<MyClass> untidyQueryable = untidyCollection.AsQueryable();

IQueryable<MyClass> sortedAndFilteredQueryable = untidyQueryable.Where(x => x.MyProperty > 100).OrderBy(x => x.MyProperty);

But now sortedAndFilteredQueryable is an IQueryable<T>, a standard interface for wrapping expressions that return something. From it we can access the underlying Expression, the base class for all expression

Expression expression = sortedAndFilteredQueryable.Expression;


if (expression is MethodCallExpression)

{

    MethodCallExpression methodCall = expression as MethodCallExpression;

    Method method = methodCall.Method;


    foreach (Expression arg in methodCall.Arguments)

    {

        //iterate through each argument

        if (arg is ConstantExpression)

        {

            //constant

        }

        else if (arg is MemberExpression)

        {

            //property or field

        }

    }

}

This capability to analyze at runtime an expression is the basis for, for example, translating expression trees to SQL or OData calls – Entity Framework, LINQ to SQL, NHibernate, WCF Data Services, all use expression trees. Unlike lambdas, which do not retain the expression used, just the result, expression trees do not execute, but instead describe a C# expression.

Auto Closing Blocks

Both Java and C# offer an interesting construct for making sure resources are released when they are no longer needed.

In C#, these resources must implement IDisposable, and the syntax for the using block is as this:

using (IDisposable ctx = new DisposableContext())

{

    //...

}

It allows multiple disposables in the same block:

using (var disp1 = new DisposableContext())

using (var disp2 = new DisposableContext())

{

    //...

}


In Java, the required interface is AutoCloseable and the feature is called try with resources:

try (AutoCloseable disp1 = new Something())

{

    //...

}

The syntax for having several auto-closing variables is also allowed:

try (AutoCloseable disp1 = new DisposableContext(), AutoCloseable disp2 = new DisposableContext())

{

    //...

}

This basically is the same as (in both languages):

MyClass c = new MyClass();


try

{

    //...

}

finally

{

    if (c != null)

    {

        c.Dispose();    //C#

        c.close();      //Java

    }

}

Conclusion

Well, not exactly a conclusion! There will be more posts, keep dropping by and sending your feedback! Winking smile

Again, I need to thank Roberto Cortez (@radcortez) for his review of the Java parts! Thanks, man! Winking smile

Java vs C# – Part 1

Disclaimer: long post!

Introduction

While some of my friends and colleagues seem to think that I don’t like Java and that I am some sort of Microsoft/.NET zealot, that is actually not true! Smile with tongue out I do like Java, and I worked with it several years.

There are several articles out there on the differences and similarities between C# and Java, but none actually satisfied me. In this new series of posts, I will try to explain these similarities and differences, as extensively and accurately as I can. I don’t want to start a religious war, but I won’t refrain from emitting judgments on what I think is best in each. I will try to cover as much as I can, but I won’t drill into APIs, instead will focus on each language’s intrinsic characteristics.

This first post will focus on high-level constructs, what I call structure: namespaces and types. I will be covering Java 8 and C# 5, the latest (as of February 2015) versions of these languages.

Update: See the second post here.

Similarities

Both languages (Java and C#) are case-sensitive, strictly object oriented, offering classes, enumerations and interfaces, single inheritance model and all of the types live in namespaces/packages. Also, all support attributes/annotations, methods and fields, including static ones. The base class for all types, in both cases, is called Object. Both have the same basic operators, comparable base types and exception handling mechanisms. Both start executing by a static method called main/Main.

Compiled Units

A Java class compiles to an identically-named class file; these files exist on their own, but are usually stored together inside a jar, war or ear, which are basically ZIP files with a manifest file attached to, for better manageability. These files, of course, can contain other resources, such as images or text files.

C# classes always exist in binary assemblies, which can have two basic forms (extensions):

  • dll: a library, does not run on its own;
  • exe: a stand-alone executable, which can either be a Console or a Windows Forms / Windows Presentation Foundation graphical application.

Assemblies can also include metadata and embedded resources, of any type. C#/.NET actually defines another compilation unit, the module, but typically a module matches an assembly, although it is possible to have it other way, for more advanced scenarios.

Namespaces

Both in Java and in C# we have the notion of namespaces or packages, which can be nested. In C#, the namespace declaration must wrap all of its types, and therefore we can have several namespace declarations in a source file, even nested:

namespace MyNamespace1

{

    public class Class1

    {

    }

}


namespace MyNamespace2

{

    public class Class2

    {

    }


    namespace MyNamespace3

    {

        public class Class3

        {

        }

    }

}

In Java, the package declaration goes on the top of a source file, meaning, it can only contain a single package:

package myPackage;


public class MyClass

{

}

There is one important difference between Java and C#: in Java, the namespace must be identical to the physical folder structure, that is, a class belonging to the a.b package must be physically located in an a\b folder; Java won’t compile it otherwise. The generated .class file must be located in the same folder, such as a\b\MyClass.class.

Java and C# can simplify accessing classes in other namespaces/packages by importing these, like we see here for Java, where we can import all types (*), or a type at a time:

//import java.lang.*;    automatically imported

import java.io.*;

import java.lang.reflect.Array;

Java imports automatically the types in the java.lang package, C# does not automatically import any namespace, and it doesn’t allow importing a single type:

using System;

using System.IO;

But it also lets us define type aliases per source file using the same syntax:

using date = System.DateTime;


public class MyClass

{

    public date GetCurrentDate()

    {

        //...

    }

}

Top Level Elements (Types)

Java and C# offer a very close syntax, in some cases, if we discount the different language conventions, it’s really hard to tell one from the other, but there are some important differences.

Java offers the following top level elements, besides packages:

  • Classes (including generic);
  • Interfaces (including generic);
  • Enumerations.

And C# the same plus some more:

  • Classes (including generic);
  • Interfaces (including generic);
  • Enumerations;
  • Structures;
  • Delegates (including generic).

Basic Types

The basic types in the two languages (C#/Java) are:

  • Object/Object (C# shorthand: object);
  • String/String (C# shorthand: string);
  • Byte/byte (C# shorthand: byte);
  • SByte/N/A (C# shorthand: sbyte);
  • Boolean/boolean (C# shorthand: bool);
  • Char/char (C# shorthand: char);
  • Int16/short (C# shorthand: short);
  • UInt16/N/A (C# shorthand: uint);
  • Int32/int (C# shorthand: int);
  • UInt32/N/A (C# shorthand: uint);
  • Int64/long (C# shorthand: long);
  • UInt64/N/A (C# shorthand: ulong);
  • Single/float (C# shorthand: float);
  • Double/double (C# shorthand: double);
  • Decimal/N/A (C# shorthand: decimal);
  • dynamic/N/A;
  • Arrays.

As you can see, C# offers unsigned and signed versions of all integer types and also a high-precision Decimal type. It also as a dynamic type, used for late-binding (runtime) operations without strong compile-time checks.

C# offers three kinds of arrays:

  • Single dimension: int [] numbers;
  • Multi dimension: int [,] matrix;
  • Arrays of arrays, also called, jagged arrays: int [][] matrix;

Java also has single dimension and jagged arrays, but no multi dimension ones.

C# lets us use the var keyword for declaring a variable and automatically initializing it. This is a shorthand for the initialization’s type:

var i = 10;            //int

var s = "string";      //string

var f = SomeMethod();  //method's return type, except void

In C# as in Java, we can specify suffixes for clarifying the desired type of a literal:

  • 10n: integer;
  • 10l: long;
  • 10f: float;
  • 10d: double;
  • 10u: unsigned int (C# only);
  • 10ul: unsigned long (C# only);
  • 10m: decimal (C# only).

Both lowercase or uppercase letters are allowed as the suffix.

Classes

Classes in Java and C# are allocated in the heap. A class can inherit from a single base class, if not specified, it will inherit from Object. It can implement any number of interfaces.

Structures

C# has a unified type system, meaning, primitive types (integers, floating points, booleans, etc) coexist in the same type hierarchy as composite classes. This is different in Java, where, for example, the int and Integer types are not related, even if it is possible to convert between the two. All primitive types in C# are structures, not classes, which means they are allocated in the stack instead of the heap. In Java this also occurs for primitive types, but there is no notion of explicit structures, and we can’t build our own types to be stored in the stack. A structure in C# cannot inherit from any class explicitly, but it can implement any number of interfaces, and also cannot declare a destructor/finalizer:

public struct MyStructure : IMyInterface

{

    public void MyMethod()

    {

    }

}

Structures and enumerations in C# are called value types and classes and interfaces are called reference types. Because of C#’s unified type system, a structure always implicitly inherits from System.ValueType.

Interfaces

In C#, an interface can only have:

  • Instance method declarations;
  • Instance property declarations;
  • Instance event declarations.

It can be generic or non-generic. Both classes and structures can implement interfaces. An interface can always be assigned null, it is a reference type. Also, a generic interface in C# can be made covariant or contravariant.

In Java, things are a bit different, since they can have also have statics and (the horror!), method implementations:

  • Instance method declarations;
  • Fields (always implicitly static) with a value (constants);
  • Default methods: methods with default implementations.

They can also be generic or otherwise, and can be implemented by enumerations. In Java, an interface’s members can also have visibility levels defined, that is, they are not always public.

If a Java interface only has one method, or, at least, one non-default method (more on this later), it can be marked as a functional interface, in which case, it can be used in lambda functions, the method is implicitly called (see an example below in the Delegates section).

Generic Types

Generics are quite different, internally, in Java and C#. Both languages support generic classes and interfaces, but in C# they are a first-class construct, with reflection support, but in Java they cease to exist once a generic class is compiled. That is, in Java, a List<String>, at runtime, becomes just List, the generic parameter String is erased, this is in order to ensure backward compatibility with prior Java versions that didn’t have generics. This doesn’t happen in C#, and we can at runtime reflect on a generic class and its parameters.

Both languages support any number of generic parameters and constraints on them. In C# these constraints are:

  • Base class, structure or interface: forces the generic parameter to inherit or implement from a specific class, structure or interface;
  • Public non-abstract class with a public parameterless constructor: only allows generic parameters that are non-abstract (or interfaces) and have a public constructor that doesn’t take parameters;
  • Reference or value type: a generic parameter either has to be a reference (class or interface) or a value type (structure or enumeration), as specified.

An example:

public class GenericClassWithReferenceParameter<T> where T : class

{

}


public class GenericClassWithValueParameter<T> where T : struct

{

}


public class GenericClassWithMyClassParameter<T> where T : MyClass

{

}


public class GenericClassWithPublicParameterlessParameter<T> where T : new()

{

}


public class GenericClassWithRelatedParameters<K, V> where K : V

{

}


public class GenericClassWithManyConstraints<T> where T : IDisposable where T : new() where T : class

{

}

Java accepts the following constraints:

  • Base class: a generic parameter must inherit from a base class;
  • Implementing interface: a generic parameter must implement some interface;
  • Unbounded generic type: a generic parameter must inherit/implement some generic type.

Some examples:

public class GenericClassWithBaseClassParameter<T extends BaseClass>

{

}


public class GenericClassWithInterfaceParameter<T extends Interface>

{

}


public class GenericClassWithBaseMatchingParameter<T, ? super T>

{

}


public class GenericClassWithManyInterfaceParameters<T implements BaseInterface1 & BaseInterface2>

{

}


In Java, we can specify a generic of an unknown type:

MyInterface<?> var;

Java also has some terrible limitations:

  • There cannot be generics of primitive types, for example, MyGenericClass<int>, only of non-primitives, like MyGenericClass<Integer>;
  • There cannot be generic arrays.

Because C# supports any kinds of generic parameters, if we want to initialize explicitly some variable of a generic parameter type, we need to use the default keyword:

public class MyGenericClass<T>

{

    public void MyMethod()

    {

        T someField = default(T);

    }

}

Finally, the base class of some class inheriting from a generic type is not that generic type, but its base class, which can seem awkward. This happens in C# and in Java.

Delegates

A delegate in C# is a method signature, composed of:

  • A name;
  • A return type;
  • Parameters (number and type).

Delegates are the building blocks of events. A delegate can either point to a static, an instance or an anonymous method (lambda), provided the signature is the same:

public delegate double Operation(double v1, double v2);


//a delegate pointing to a static method

Operation addition = Operations.Add;


//a delegate pointing to an instance method

Operation subtraction = this.Subtract


//a delegate pointing to an anonymous method using lambdas

Operation subtraction = (a, b) =>

{

    return a + b;

};

A delegate can be generic:

public delegate void Action<T>(T item);

Delegates inherit automatically from System.Delegate, because of this, they have built-in support for dynamic and asynchronous invocation.

Java has a similar construct, functional interfaces. These are interfaces with a single non-default method, which can be used in lambda functions:

public interface MyWorkerFunction

{

    @FunctionalInterface

    public void doSomeWork();

}


public void startThread(MyWorkerFunction fun)

{

    fun.doSomeWork();

}


public void someMethod()

{

    startThread(() -> System.out.println("Running..."));

}

If an interface is marked as functional but has more than one method, it will not compile.

Enumerations

Enumerations in Java can have members (constructors, fields and methods) and even implement interfaces, something that is not possible in C#:

public enum MyEnumeration implements MyInterface

{

    A_VALUE(1),

    ANOTHER_VALUE(2);


    private int value;


    private MyEnumeration(int value)

    {

        this.value = value;

    }


    public static String fromInt(int value)

    {

        if (value == A_VALUE.value) return ("A_VALUE");

        else return ("ANOTHER_VALUE");

    }

}

In C#, no methods or interfaces, but we can have an enumeration be implemented based on a primitive integer type, including unsigned (the default is signed int):

public enum MyEnumeration : uint

{

    AValue = 1,

    AnotherValue = 2

}

Implicitly, all C# enumerations inherit from System.Enum.

In both cases, C# and Java, we can specify integral values for each enumeration member, and, if we don’t, members will get sequential values.

Type Visibilities

A type in Java has four possible visibilities:

  • package: only accessible by other classes in the same package (the default);
  • public: accessible by everyone.

And C# types have similar ones, plus one:

  • internal: only accessible by other classes in the same assembly (the default);
  • public: accessible by everyone.

Inheritance

In C#, the syntax for extending a class and for implementing an interface is exactly the same:

public class MyClass : BaseClass, IInterface

{

}

Whereas in Java there are the extends and the implements keywords, respectively, for classes and interfaces:

public class MyClass extends BaseClass implements Interface

{

}


public interface DerivedInterface extends BaseInterface1, BaseInterface2

{

}

Both can inherit from a single class and implement as many interfaces as desired. Also, an interface can itself inherit from several interfaces.

In C# it is possible to implement interfaces in one of two ways:

  • implicit: where the interface’s members are directly accessed through the implementing class;
  • explicit: where we have to cast the class to the explicitly implemented interface before we can use it; this is useful, among other reasons, if we want to implement several interfaces which offer identically-named members.

Let’s see how they look in C#, in this example, interface IMyInterface1 is explicitly and IMyInterface2 implicitly implemented:

public class MyClass : IMyInterface1, IMyInterface2

{

    void IMyInterface1.MyMethod1()

    {

    }


    public void MyMethod2()

    {

    }

}

Explicitly-implemented members are always private and cannot be virtual or abstract. If we want to call a method or access a property of an explicitly implemented interface, we need to cast the instance first:

MyClass c = new MyClass();

IMyInterface1 i = (IMyInterface1) c;

i.MyMethod();

Java only has implicit interface implementations:

public class MyClass implements MyInterface

{

    public void myMethod()

    {

    }

}

Inner Classes

In Java as in C#, we can have multiple levels of nested/inner classes, structures and interfaces, but in Java they can be static or instance:

public class MyClass

{

    public static class MyStaticInnerClass

    {

    }


    public class MyInnerClass

    {

    }

}

Instance inner classes can only be instantiated when we have an instance of its containing class (do notice the awful syntax):

MyClass.MyStaticInnerClass c1 = new MyClass.MyStaticInnerClass();


MyClass c2 = new MyClass();


MyClass.MyInnerClass c3 = c2.new MyInnerClass();

In C#, any inner class can be instantiated, with or without an instance of the containing class, provided its visibility level is respected:

public class MyClass

{

    public class MyInnerClass

    {

    }

}


MyClass.MyInnerClass c = new MyClass.MyInnerClass();

For C# the following visibility levels exist:

  • internal: only accessible by other classes in the same assembly (the default);
  • protected: only accessible by descending classes;
  • protected internal: derived classes or classes from the same assembly;
  • private: only accessible by the declaring class;
  • public: accessible by everyone.

Whereas for Java:

  • package: only accessible by other classes in the same package (the default);
  • protected: only accessible by descending classes;
  • private: only accessible by the declaring class;
  • public: accessible by everyone.

Abstract Classes

In Java as in C# we have abstract classes, and the syntax is exactly the same:

public abstract class MyClass

{

    public abstract void myMethod();

}

C# structures cannot be abstract.

Sealed Classes

Both frameworks allow a class to be marked as sealed/final, meaning, it cannot be inherited from:

public sealed class MyClass

{

    //a C# sealed class

}

public final class MyClass

{

    //a Java final class

}

C# structures are always implicitly sealed.

Static Classes

In C# we can have static classes, which are roughly equivalent to being at the same time abstract and sealed. Static classes only allow static members (properties, methods, fields and events):

public static class MyClass

{

    public static void MyMethod()

    {

    }


    public static string MyField;


    public static int MyProperty { get; set; }


    public static event EventHandler MyEvent;

}

Java does not have the concept of static classes.

Nullable Types

Because it is allocated in the stack, a variable of a structure or enumeration type always has a value, so, it cannot be null, but we can use a handy syntax to turn it into a nullable type, which can itself be made null:

int ? nullableInteger = null;

nullableInteger = 1;


if (nullableInteger.HasValue)    //if (nullableInteger != null)

{

    int integer = nullableInteger.Value;    //int integer = nullableInteger

}

In Java, primitive values can never be null, we need to resort to their corresponding wrapper classes:

Integer nullableInteger = null;

nullableInteger = new Integer(1);

Classes and interfaces in C# (reference types) are always nullable, meaning, can always be assigned null.

Partial Classes

C# allows marking a class as partial, meaning, its contents may spread through several different source files; the actual compile-time class will be built from all of these files. This is very useful when we have automatically generated files that we don’t want to change, but rather complement:

//in file MyClass.Generated.cs

public partial class MyClass

{

    public void OneMethod()

    {

    }

}


//in file MyClass.cs

public partial class MyClass

{

    public void AnotherMethod()

    {

    }

}

Anonymous Classes

Java has anonymous classes: we can create anonymous classes that implement some interface or extend some class, by implementing all of its abstract methods:

this.addEventListener(new ListenerInterface

{

    public void onEvent(Object source, Event arg)

    {

    }

});

Anonymous classes in C# do not contain explicitly defined methods, only read-only properties; two anonymous classes are considered of the same type if their members are declared in the same order and with the same types:

var i1 = new { A = 10, B = "" };

var i2 = new { A = 1000, B = "string" };


//these two classes have the same type

i1 = i2;

In order to support anonymous classes, C# introduced the var keyword, which allows us to have a variable infer its type automatically. An anonymous type is created when a variable is created without a static type.

Type Members

In .NET we have the following type members:

  • Constructors (static and instance);
  • Destructors;
  • Methods (static and instance);
  • Fields (static and instance);
  • Properties (static and instance);
  • Events (static and instance);
  • Overridden operators and type conversions (discussed on the next post).

Java only has:

  • Constructors (static and instance);
  • Constructor blocks;
  • Destructors;
  • Methods (static and instance);
  • Fields (static and instance).

Static Constructors

Static constructors or class initializers are basically the same in C# and Java, but have a slightly different syntax, here is the Java one:

public class MyClass

{

    static

    {

        //do something the first time the class is used

    }

}

And the C# syntax:

public class MyClass

{

    static MyClass()

    {

        //do something the first time the class is used

    }

}

Java offers another weird thing: constructor blocks. You can have any number of them, and their code will be included automatically into all of the class’ constructors:

public class MyClass

{

    {

        System.out.println("First constructor block, called before constructor");

    }


    public MyClass()

    {

        System.out.println("MyClass()");

    }


    {

        System.out.println("Second constructor block, called before constructor but after first constructor block");

    }

}

Destructors

In C# a destructor, or finalizer, is just a shorthand syntax to the Finalize method. This method is called by the Garbage Collector when an instance is about to be freed. Java has an identical method, called finalize, which serves a similar purpose. Strictly speaking, none of these methods is actually a destructor, but they are sometimes called that.

In C#, we can use the C++ syntax instead of overriding Finalize:

public class MyClass

{

    ~MyClass()

    {

        //object is being freed

    }

}

Static Members

Unlike C#, Java allows referencing static members through an instance variable, for example:

public class MyClass

{

    public static void doSomething()

    {

    }

}


MyClass c = new MyClass();

c.doSomething();

Properties

Properties are a useful C# construct, which allows a cleaner syntax to changing fields:

public class MyClass

{

    public int MyProperty { get; set; }

}


MyClass c = new MyClass();

c.MyProperty++;

We can have auto-implemented properties (such as in this example) or properties with an explicit backing field:

public class MyClass

{

    private int myField;


    public int MyProperty

    {

        get

        {

            return this.myField;

        }

        set

        {

            this.myField = value;

        }

    }

}

The Java equivalent can only be achieved with methods:

public class MyClass

{

    private int myProperty;


    public void setMyProperty(int value) { this.myProperty = value; }

    public int getMyProperty() { return this.myProperty; }

}


MyClass c = new MyClass();

c.setMyProperty(c.getMyProperty() + 1);

In C# we can also define indexed properties for classes, interfaces and structures, like in this example using an integer index:

public class MyCollection

{

    private Object [] list = new Object[100];


    public Object this[int index]

    {

        get

        {

            return this.list[index];

        }

        set

        {

            this.list[index] = value;

        }

    }

}

We are not limited to integer indexes, any type can be used as the key to an indexed property.

Finally, properties can have different visibility levels for the getter and setter methods, and can even have just one of them (usually just a setter does not make much sense):

public int InternalProperty

{

    get;

    private set;

}


public string GetOnlyProperty

{

    get

    {

        return this.InternalProperty.ToString();

    }

}

Events

Events are C#’s implementation of the Publisher/Subscriber and Observer Patterns: it allows to register methods that will be called when the event is raised, and offers a simple syntax for registering, unregistering and clearing event handlers. An event handler is just an instance of a delegate, the delegate is the event’s signature:

public class MyClass

{

    public event EventHandler MyEvent;


    public void ClearEventHandlers()

    {

        //check for registered event handlers

        if (this.MyEvent != null)

        {

            //raise event

            this.MyEvent(this, EventArgs.Empty);


            //clear event handlers

            this.MyEvent = null;

        }

    }

}


MyClass a = new MyClass();


//register event handler

c.MyEvent += OnMyEvent;


//unregister event handler

c.MyEvent -= OnMyEvent;

Like with properties, it is also possible in C# to implement the event add and remove methods explicitly, so as to add our own behavior:

public class MyClass

{

    private EventHandler myEvent;


    public event EventHandler MyEvent

    {

        add

        {

            this.myEvent += value;

        }

        remove

        {

            this.myEvent -= value;

        }

    }

}

Automatic Initialization of Fields and Properties

All fields declared in a class are initialized to their type’s default value (0 for integers and floating point number, false for booleans, null for classes). C#’s auto-implemented properties are also implicitly initialized to their type’s default value. This behavior is the same in both languages, of course, Java does not have properties.

Member Visibilities

C# has four visibility levels for members:

  • private: accessible from the declaring type;
  • internal: accessible from types in the same assembly as the declaring type;
  • protected: accessible from types inheriting from the declaring type;
  • protected internal: accessible from types either inheriting from the declaring type or from its same assembly;
  • public: accessible by everyone.

And Java, we only have:

  • package: only accessible by classes in the same package;
  • protected: only accessible by descending classes;
  • private: only accessible by the declaring class;
  • public: accessible by everyone.

Virtual Members

In Java, all methods are virtual by default (there is no virtual keyword), unless marked as final.

In C#, a method, property or event needs to be explicitly marked as virtual so that it can be overridden, and all overrides must state so:

public class MyBaseClass

{

    public virtual void MyMethod()

    {

    }

}


public class MyDerivedClass : MyBaseClass

{

    public override void MyMethod()

    {

    }

}

If a derived class member with the same name as one in the base class exists, but it is not an override of it, we need to mark it as new:

public class MyBaseClass

{

    public void MyMethod()

    {

    }

}


public class MyDerivedClass : MyBaseClass

{

    public new void MyMethod()

    {

        //no relation with MyBaseClass.MyMethod

    }

}

Sealed Members

In C# as in Java, it is possible to mark a member (method) as sealed/final, meaning, it is not available for overriding in a derived class. In C# the same applies to events and properties, which, of course, don’t exist in Java.

C# syntax:

public class MyClass

{

    public sealed void DoSomething()

    {

    }

}

And Java syntax:

public class MyClass

{

    public final void doSomething()

    {

    }

}

Abstract Members

In both languages, abstract members (methods) can exist in abstract classes, but they are not required: we can have abstract classes without any abstract members. In C#, besides methods, we can also have abstract properties and events.

Generic Methods

Methods can also be generic, regardless of living in generic classes or not. The same constraints apply, but generic methods also have automatic type inference:

public class MyClass

{

    public static int Compare<T>(T v1, T v2)

    {

        if (v1 == v2)

        {

            return 0;

        }


        return -1;

    }

}


//no need to specify the int parameter type

int areEqual = MyClass.Compare(1, 2);

Read-only and Constant Fields

Both Java and C# have read-only fields, but C# uses the readonly keyword:

public static class Singleton

{

    //a C# readonly field

    public static readonly Singleton Instance = new Singleton();

}

And Java uses final:

public class Singleton

{

    //a Java final field

    public static final Singleton INSTANCE = new Singleton();

}

C# also offers another kind of read-only field, constants. A constant is always static and can only be of one of the primitive types, or an enumerated value:

public static class Maths

{

    //a C# constant field

    public const double PI = 3.1415;

}

The difference between readonly and const is that the C# compiler inlines all constants, that is, it actually replaces any references to it by their concrete values. The Java compiler does something similar for static final fields. Read-only fields can be initialized inline, together with the field declaration, or in constructors (static or instance).

Technical Review

I couldn’t have written this post without the technical review by my friend and colleague Roberto Cortez (@radcortez), of Java fame. Thanks, Roberto! Winking smile

Next Steps

That’s it for now. Stay tuned for the next post, where I will talk about other language differences. Let me hear from you!