Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Comparative Study of Java and C#

0.00/5 (No votes)
30 Aug 2003 1  
A brief article comparing and contrasting the features of Java and C#.

Contents

  1. Introduction
  2. Object Oriented Paradigm
  3. Runtime Environment
  4. Compiling and Running from the Command Line
  5. Namespaces and Classes
  6. Aliases
  7. Pre-processor Directives
  8. Constructors, Destructors and Garbage Colection
  9. Multiple Main Methods
  10. Comparison of Keywords
  11. Constants
  12. ReadOnly Field
  13. Verbatim Strings
  14. Value Types
  15. Access Modifiers
  16. Type safety
  17. Indexers
  18. Global Methods
  19. Foreach Statement
  20. Switch Statement
  21. Goto Statement
  22. Virtual Methods
  23. Jagged Arrays
  24. Collections
  25. Enumerators
  26. Boxing
  27. Reflection
  28. Inheritance
  29. Superclass Constructor
  30. Exception Handling
  31. Thread Synchronization and Safety
  32. Pointers
  33. Structures
  34. Properties
  35. Attributes
  36. Delegates
  37. Events
  38. Files and Streams
  39. Serialization
  40. Operator Overloading
  41. Conclusion
  42. References

Introduction

C# like Java is a "simple, object oriented, distributed, interpreted, robust, secure, portable, high performance, multithreaded and dynamic language". C# goes a step further and implements features like "cross-language interoperability" and "mixed language programming". It supports component-based programming and is well suited for distributed web applications. Not being closely coupled with Windows OS could be considered as another drawback of Java since Windows is the most widely used operating system. Even though both Java and C# have inherited features from C and C++, C# cannot be considered as a successor of Java. Rather, they could be considered as peers, having a lot in common but unique in their own ways. C# was developed keeping the .NET platform in consideration, and hence is the most likely choice for developing .NET applications. In short, C# is a simple but a powerful language which is conceptually like C, powerful like C++, elegant like Java, and useful like VB.

Object Oriented Paradigm

Both Java and .NET treat data as a critical element in program development. Every problem is decomposed into a number of entities called 'objects' and then build data and functions around these entities. A software object consists of a set of related data and functions. Both follow a single rooted object hierarchy. Every class in the Java framework is a subclass of java.lang.Object and every class in the .NET framework is a subclass of System.Object.

Runtime Environment

CLR (Common Language Runtime) manages the execution of programs in the .NET environment. When a C# code is compiled, the output is not an executable but an intermediate code, called the MSIL (Microsoft Intermediate Language). MSIL is a set of assembly level instructions that are platform independent and conceptually equivalent to the byte codes in Java. The CLR then translates the MSIL into executable code when run using the JIT (Just In Time) compiler. CLS (Common Language Specification) is a set of rules the .NET compiler should adhere to so as to facilitate interoperability with other languages. CTS (Common Type System) is a subset of the CLS and it must be implemented by every .NET compiler. CLS and CTS are both implemented by C#. Most importantly, the specification has been opened up (using open standard technologies like XML and SOAP), so that it can be ported to non-Windows platforms. The CLR is well designed as compared to the JVM (Java Virtual Machine) and supports execution of both managed and unmanaged code. .NET can be considered as an extension of CLR with extra features like Windows Forms and Enterprise Services. The basic difference between the JVM and C# is that the C# compiler produces an executable code.

Compiling and Running programs from Command Line

In Java:

> javac <program_name>.java
> java <program_name>

In C#:

> csc <program_name>.cs
> <program_name>

C# has a highly sophisticated IDE, Visual Studio .NET, better than any of the Java IDEs.

Namespaces and Classes

Namespaces are used to semantically group elements for organization and readability of classes and other namespaces. Names declared in one namespace will not conflict with the names declared in another namespace. It can be nested to any level. They are analogous to packages in Java.

package mySpace1.mySpace2.mySpace3;
class FirstClass
{
}

A specification in Java (shown above) would be equivalent to the code shown below in C#:

namespace mySpace1
{   namespace mySpace2
   {
     namespace mySpace3
      {
            class FirstClass
            { 
             }
      }
   }  
}

Aliases

The using directive in C# is equivalent to the import directive in Java. A fully qualified name can be substituted with an alias, just like typedef is used in C and C++. This is done to improve readability.

using printpath = System.Console; 
class testApp{   
    static void Main ( ) { printPath (�Alias test�); }     
}

Pre-processor Directives

Unlike in Java and like in C/C++, C# supports the use of pre-processor directives  like #define, #undef, #if, #elif, #else, #endif, #warning, #error, #line, #region, #endregion. However, C# does not support macros.

Constructors, Destructors and Garbage Collection

In both Java and C#, classes are instantiated using the new keyword. The constructor initializes an object when it is created and its syntax is same as that in Java.

<access modifier>  <classname> 
{ 
     /* constructor code */ 
}

Recovery of memory from unused objects is a key aspect of dynamic allocation scheme. In C#, this is accomplished in the following two ways:

  1. It does have a Java like �garbage collection� scheme in which system sporadically reclaims memory from objects automatically which occurs without the knowledge of the programmer.
  2. A destructor can be called explicitly just like in C++. This is similar to finalizer method in Java.
~<classname> 
{ 
     /* constructor code */ 
}

Multiple Main methods

Unlike Java, C# supports use of multiple main methods in a single class. It is used to test the class against several test cases.

 MultipleMain.cs /main:<class name>

Comparison of Keywords

Unlike Java, all data types in C# are objects. The keyword set in C# is richer since it has lot more keywords than Java. C# contains the following keywords in addition to almost every keyword contained in Java: as, byte, checked, decimal, delegate, enum, event, explicit, fixed, foreach, get, implicit, in, object, operator, out, override, params, readonly, ref, set, sizeof, stackalloc, string, struct, typeof, uint, ulong, unchecked, unsafe, ushort, value, and virtual.

Constants

Java uses the static final keyword and C# uses the const keyword to declare constants.

ReadOnly field

This is similar to the directive final in Java, but it will not get its value until runtime and once initialized, the value remains unchanged till the end.

Verbatim Strings

The Verbatim string literals are defined by enclosing the required string in the characters @" and ". Verbatim string syntax can span multiple lines and white space is preserved. This is a unique feature of C#.

string pathname = @"C:\Programs\"

Value Types

For efficiency purposes, CTS (Common Type System) is divided into 2 categories:

  1. Value types: This variable contains actual data. It always contains a value, and it can't be null.

    E.g.: enumerators, structures and primitives.

  2. Reference types: This refers to the address of an object that is of the type specified and has already been allocated (type-safe pointer). When null, it signifies that it does not refer or point to any object.

    E.g.: classes, arrays, interfaces, delegates.

Access Modifiers

The scope of the protected access modifier is slightly different from that of the protected access modifier in Java. A protected entity (method or data) can only be accessed by the same class or its sub classes. The internal access modifier in C# is equivalent to the protected access modifier in Java. By default, access modifiers of all methods in C# are private but that of Java are protected. C# also has the internal protected access modifier.

Type Safety

C# is a robust language and provides number of type safety measures. It does not permit unsafe casts, checks for array bounds, reference parameters passed are type safe, and all dynamically allocated objects are initialized to zero.

Indexers

An indexer allows an object to be indexed like an array. Both Java and C# support indexers. The main use of indexers is to support the creation of specialized arrays that are subject to constraints.

element_type this [int index] 
get{ 
    /* return the value specified by index */ 
} 
set{   
    /* set the value specified by the index */ 
}

Global Methods

Like in Java, methods have to be a part of a class and no global methods are allowed. Both support automatic destruction of objects when they are out of scope (or do not have any references) and memory management.

foreach statement

The foreach loop is a variation of the for loop in C++ which used to cycle through the elements of a collection of objects.

Switch statement

The switch statement in C# is an enhanced version of switch statement in Java. C# supports use of string literals in the switch statement. It also does not allow fall through unless the labels contain no code.

Goto statement

Java does not support �goto� statement. Even though much maligned, C# supports the goto statement for better code reusability and clarity.

Virtual methods

In Java, all methods are virtual methods by default. C# follows the C++ model in which the methods must be explicitly specified as virtual using the virtual keyword. In subclasses, the virtual method can be explicitly overridden by using the override keyword or explicitly choose not to, by using the new keyword.

Jagged Arrays

Jagged array is a unique feature of C#. It is an array of arrays in which each array is of variable size. It can be considered as a table in which the lengths of all the rows are not the same. Java has no provision for such an array.

Collections

Both in Java and C#, a collection is an object that groups multiple elements into a single unit. Collections are used for storing, retrieving, manipulating and transmitting data from one method to another. The System.Collections in C# contains a set of well defined interfaces and classes that implement various types of collections. They simplify programming tasks as they contain built in interfaces such as arraylists, stacks, queues, hash tables etc.

Enumerator

An enumerator is a special kind of value type limited to a restricted and unchangeable set of numerical values. When you define an enumerator, you provide literals which are then used as constants for their corresponding values. For the first literal, if its value is unassigned, its value is set to 0. For all other literals, the value is set one more than its preceding literal.

public enum Days { 
    Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
}

Boxing

In Java, the primitive data types have to be placed in the appropriate wrapper classes before being used as 'objects'. In C#, this is done by 'boxing' in which the wrapper class is implemented implicitly without exposing the programmer to it. C# allows conversion of any value type to a corresponding reference type, and to convert the resultant 'boxed' type back again. This is used when value types are to be accessed as objects.

int val = 101;
object box = val;
if (box is int) 
{ 
    Console.Write ("Box contains an int"); 
}

Reflection

Reflection enables one to find out the type of an object. The Type object is queried and it reflects the information associated with the type back. It is a powerful mechanism since one can learn and use the capabilities of types that are known only at runtime. Reflection is supported by both Java as well as C# but their implementation varies slightly. In Java, the reflection is done at class level and in C#, reflection is done at the package level.

C# also has 3 keywords for runtime type identification.

  1. is: C# uses the is operator to determine whether an object is of a certain type. It is analogous to the instanceof operator in Java.
  2. as: C# uses the as operator to cast at runtime. If the cast succeeds. the type information is returned or a null reference is returned.
  3. typeof: C# uses typeof operator to get the System.Type for a given object, using which all the characteristics of the object can be determined.

Inheritance

Both C# and Java support single level inheritance only, and multi-level inheritance is accomplished by implementing interfaces. Both Java and C# can block inheritance of a class using the keyword final and sealed respectively.

Superclass Constructor

base( ) in C# is identical to super( ) method call in Java which enables you to call the constructor of the base class.

Exception Handling

Both languages use the try and catch blocks for exception handling. The try block indicates the region under inspection and the catch block handles the exceptions. There can be multiple catch blocks to handle multiple exceptions and the finally block for handling any of the exceptions not handled by the previous catch blocks. This code will run whether or not an exception is generated.

Thread Synchronization and Safety

C# uses the lock keyword which is identical to the synchronized keyword in Java. Like in Java, C# also supports the concept of synchronized methods. A lock statement ensures that the section of the code segmented protected by the lock for the given object can be used only by the thread that gets the lock. All other threads are blocked until the lock is released. The lock is released when the block is exited. This is accomplished using the Monitor class in C#.

lock (object)
{
    /* code to be synchronized */
}

Pointers

Java does not support pointers. A major problem with using pointers in C# is that there is a background automatic garbage collection process in operation. Trying to free memory, garbage collection could change the memory location of a current object without the programmer�s knowledge. So any pointer which previously pointed to that object will no longer do so. This could compromise the running of the C# program and could affect the integrity of other programs. Therefore the code using pointers has to be explicitly marked by the programmer as unsafe.

ref, out (like pointers in C) tells the C# compiler that the arguments being passed point to the same memory as the variables in the calling code. ref implies that the variables have to be initialized. out implies that initialization of variables is not necessary.

Structures

C# supports structures which are value types and is allocated once declared. It is an error to create a parameter-less constructor for a struct. It is used only when the data being contained is very small, and has very few or no methods.

Properties

Property combines a field with the methods that access it. It consists of a name along with get and set accessors.

<return type> name
{       
    get { /* get accessor code */  } 
    set {  /* set accessor code */  }
}

Attributes

C# allows addition of declarative information to the program in the form of an attribute. An attribute defines additional information associated with a class, structure or a method. It is not a member of a class and it only specifies additional information that is attached to an item. Java too has a well developed API that supports attributes.

Delegates

Delegate is an object that can refer to a method, and that method can be invoked through this reference. The same delegate can be used to invoke different methods during runtime by simply changing the method to which the delegate refers.

delegate <return_type> <delegate_name> (parameter list);

Events

An event is an automatic notification that some action has occurred. An object that has an interest in an event registers an event handler for that event. When the event occurs, all registered handlers are called. Both Java and C# support event handling. In C#, event handlers are represented by delegates.

event <event_delegate> object;

Files and Streams

In both C# and Java, I/O and file handling operations are implemented using streams.

Serialization

Serialization is the mechanism used by the .NET environment to support streaming of user-defined types. It allows you to read and write objects through a stream such as file. It is also known as Object Persistence because it retains the state of the object when it is in some form of storage or when it is transferred from one place to another. Serialization is the best means of transferring the representation of a class in an automatic and seamless manner. Serializable objects in C# are specified with the [Serializable] attribute. Members that should not be serialized are specified using the [Nonserialized] attribute. In C#, the serializable members are stored in 2 formats:

  1. XML: This is human understandable.
  2. Binary format: Machine readable.

Serialization of objects can also be customized using the ISerializable interface. Serializable objects in Java implement the Serializable interface. The transient keyword is used to specify members that are not to be serialized. The default serializable format in Java is binary, but it allows customization of format.

Operator Overloading

Java does not provide for operator overloading, whereas C# like in C++ supports operator overloading.

Conclusion

Both Java and C# with their well developed APIs, are extremely competent programming languages in their own right, and have revolutionized the world of programming. Competition between C# and Java is one of the best things that has happened to the software industry in a long time. C# being the latest one has had the chance to rectify certain shortcomings of Java, while Java has the advantage of being the already established language. The ultimate result has been better programming practices and hence better applications. The programmer now has an option to choose from the rich set of features available in Java or .NET platforms according to his needs. The Visual Studio IDE is an outstanding piece of work and will go a long way in increasing the popularity of .NET technology. One can confidently say that completely unseating Java and replacing it with .NET  would be an uphill task. But C# takes the best from the past and incorporates the latest and the best in modern computer language design, hence carving a niche for itself as one of the best programming languages ever.

References

Books:

  1. Inside C#, Tom Archer and Andrew Whitechapel, Microsoft Press, ISBN 0735616485
  2. C#: The Complete Reference, Herbert Schildt, McGraw-Hill Osborne Media, ISBN 0072134852
  3. .NET Development for Java Programmers, Paul Gibbons, APress Publishers, ISBN 1590590384
  4. Java in a Nutshell, David Flanagan, O'Riley and Associates Inc., ISBN 156592262X
  5. Programming in C#, E. Balagurusamy, Tata McGraw Hill Publishers, ISBN 0070473390

Web Sources:

  1. MSDN
  2. SUN
  3. SoftSteel

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here