Jump to content

Comparison of C Sharp and Java: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Line 103: Line 103:
[[Java Webstart]] and Java [[applet]]s provide convenient, lightweight and secure means of distributing an application to the desktop, while the efficiency of its [[bytecode]] representation, coupled with aggressive Java-specific compression technologies such as [[pack200]], makes Java a very bandwidth-friendly means of distributing applications over a network.
[[Java Webstart]] and Java [[applet]]s provide convenient, lightweight and secure means of distributing an application to the desktop, while the efficiency of its [[bytecode]] representation, coupled with aggressive Java-specific compression technologies such as [[pack200]], makes Java a very bandwidth-friendly means of distributing applications over a network.


=== .NET framework ===
=== .NET framework and Java Runtime Environment ===


The [[.NET Framework]] is roughly comparable to [[Java Runtime Environment]] (JRE). They are not parts of the languages themselves, rather they are libraries to be used by programs which are developed using the languages.
The [[.NET Framework]] is roughly comparable to [[Java Runtime Environment]] (JRE). They are not parts of the languages themselves, rather they are libraries to be used by programs which are developed using the languages.

Revision as of 08:45, 23 September 2006

#

This is a comparison of the C# programming language with the Java programming language. As two modern garbage-collected runtime-compiled languages derived from C and C++, Java and C# are very similar. This page documents the strong general similarities of the languages and then points out those instances where the languages diverge. Both languages were designed carefully, and if one language has a feature another lacks it is the result of a conscientious design decision. Thus, the reader is advised to avoid the temptation to 'keep score,' and instead think about why the designers made each decision.

Language

Object handling

Both languages are object oriented from the ground up, with a syntax similar to C++. (C++ in turn is derived from C.) Neither language is a superset of C or C++, however. Both use garbage collection as a means of reclaiming memory resources, rather than formal deallocation of memory. And both include thread synchronization mechanisms as part of their language syntax.

Both Java and C# have strong and weak object references. Java allows registering a listener that will be notified when a reference is garbage collected, which allows for the good performance of the WeakHashMap that C# lacks. C# also supports execution of user code when an object is garbage collected, but the mechanism is the special "finalize" method.

C# allows the use of pointers, which some language designers consider to be unsafe. C# addresses that concern by requiring that code blocks or methods that use the feature be marked with the "unsafe" keyword, so that all clients of such code can be aware that the code is less secure than otherwise. It also requires the /unsafe switch to be set when compiling to allow the compilation of the code.

Data types

C# permits the definition of value types as "structs" — similar to classes but allocatable on the stack. C# has more primitive types than Java, with unsigned as well as signed types being supported. Java forgoes most unsigned types in favour of greater efficiency at the bytecode level. The biggest complaint here is that Java lacks an unsigned byte primitive.

Both languages support the idea of primitive types, and both allow boxing and unboxing to translate primitive data to and from object form. Strings are treated as objects, but support for string literals provides a specialised means of constructing them. Array and collection types are also given significance in the syntax of both languages, thanks to a modified iterator-based for loop, commonly known as foreach. Object types can be parameterized, to allow for generic programming. However, Java's generics employ erasure, making them compile time only.

Enumerations in C# use a primitive as the data. All valid values of the primitive are valid values of the enum. This allows for ORing of flags together. Enumerations in Java are objects. The only valid values in a Java enumeration are the ones listed in the enumeration. A special enumeration set object is needed to perform the equivalent ORing of flags. Java enumerations allow different method implementations for each value in the enumeration. Java Enumerations are also supported in switch statements and can convert to and from Strings.

There are no unsigned primitive numeric types in Java. While it is universally agreed that mixing signed and unsigned variables in code is bad, Java's lack of support for unsigned numeric types makes it somewhat unsuited for low-level programming.

C# has true multi-dimensional arrays, as well as the array-of-arrays that is available to Java (which C# calls jagged arrays). Multi-dimensional arrays are always rectangular (in the 2D case, or analogous for more dimensions), whereas an array-of-arrays may store rows (again in the 2D case) of various lengths (So called "jagged" arrays). Rectangular arrays may speed access if memory is a bottleneck (there is only one memory reference instead of two; this benefit is very dependent on cache behavior) while jagged arrays save memory if it's not full but cost (at the penalty of one pointer per row) if it is. Rectangular arrays also obviate the need to allocate memory for each row explicitly.

Java 1.5's generics use type erasure. Information about the generic types is ignored at runtime, and only obtainable via reflection on the static class objects. .NET 2.0's generics are preserved at runtime due to generics support starting in version 2.0 of the .NET Common Language Runtime, or CLR for short. Java's approach requires additional type checks, does not guarantee that generic contract will be followed, and lacks reflection on the generic types. In both Java and C#, generic specializations that use different reference types use equivalent underlying code. ("For all reference types we share the code, because they are representationally identical. It's just pointers." --Anders Hejlsberg, Generics in C#, Java, and C++.) In .NET 2.0's generics, type safety is enforced at load time by the VM, whereas in Java, type safety is only partially enforced and can be taken into account only at compile time, as the Java VM is not aware of generic types. The .NET runtime can also dynamically create new specializations of generic types at runtime.

Notation and special features

Java has a static import syntax that allows using the short name of some or all of the static methods/fields in a class.

Special feature keywords

keyword feature, example usage
get/set C# implements properties as part of the language syntax.
out C# has support for output parameters, aiding in the return of multiple values.
switch In C#, the switch statement also operates on strings.
strictfp Java uses strictfp to guarantee the result of floating point operations remain the same across platforms.
using C#'s using forces the object created to be disposed after the code block has run.
// SomeClass implements the IDisposable interface
using (SomeClass an_instance = new SomeClass())
{
   Console.WriteLine(an_instance.a_field);
}
// an_instance is now out of scope and disposed
goto C# supports the goto keyword. This can occasionally be useful, but the use of a more structured method of control flow is usually recommended. A common use of the goto keyword in C# is to transfer control to a different case label within a switch statement. Both C# and Java allow qualified breaks and continues, which make up for many of the uses of goto.
switch(a_enum_instance)
{
   case SomeEnum.blue: Console.WriteLine("Color is blue"); break;
   case SomeEnum.darkblue: Console.WriteLine("Color is dark"); goto case 1;
   // ...
}

Event handling

Event handling in C# is part of the language syntax itself. C# supports anonymous delegates which provide closure functionality.

Java includes anonymous inner classes [1], whereas C# includes a delegates model of delegation.

Operator overloading

C# includes a large number of notational conveniences over Java, many of which, such as operator overloading and user-defined casts, are already familiar to the large community of C++ programmers. It also has "Explicit Member Implementation" which allows a class to specifically implement methods of an interface, separate to its own class methods.

Java does not include operator overloading, because abuse of operator overloading can lead to code that is harder to understand and debug. C# allows operator overloading, which, when used carefully, can make code terser and more readable. Java's lack of overloading makes it somewhat unsuited for certain mathematical programs. Conversely, .NET's numeric types do not share a common interface or superclass with add/subtract/etc. methods, restricting the flexibility of numerical libraries.

Methods

Methods in C# are non-virtual by default. In Java however, methods are virtual by default. Virtual methods guarantee that the lowest-level override of a method will be called. The JVM or CLR makes a run-time determination of the correct method to call. If the method is declared as non-virtual, the method to invoke will be determined by the compiler. This is an important difference between Java and .NET platforms, one that a programmer needs to be aware of.

Namespaces and source files

C#'s namespaces are more similar to those in C++. Unlike Java, the namespace does not specify the location of the source file. (Actually, it's not strictly necessary for a Java source file location to mirror its package directory structure.)

Java requires that a source file name must match the only public class inside it, while C# allows multiple public classes in the same file.

Exceptions

Java support for checked exceptions enforces error trapping and handling. C# does not include checked exceptions. Some would argue that checked exceptions are very helpful for good programming practice. Others, including Anders Hejlsberg, chief C# language architect, argue that they were to some extent an experiment in Java and that they haven't been shown to be worthwhile [2] [3]. One criticism of checked exceptions is that if you change the internals of a function, that may cause new exceptions to be thrown, which would cause a contract-breaking change for any checked exceptions. To preserve interface compatibility, many functions end up declaring "throws Exception", which completely defeats the purpose of checked exceptions.

Lower level code

The Java Native Interface (JNI) feature allows Java programs to call non-Java code. However, JNI does require the code to be called to follow several conventions and impose restrictions on types and names used. This means that an extra adaption layer between legacy code and java is often needed. This adaption code must be coded in a non-Java language, often C or C++.

C#'s Platform Invoke (p/Invoke) offers the same capability by allowing a call to what Microsoft refers to as unmanaged code. Through metadata attributes the programmer can control exactly how the parameters and results are marshalled, thus avoiding the need for extra adaption code.

C# also allows the programmer to disable the normal type-checking and other safety features of the CLR, which then enables the use of pointer variables. When this feature is used, the programmer must mark the code using the "unsafe" keyword. JNI, p/Invoke, and "unsafe" code are equally risky features, exposing possible security holes and application instability. An advantage of unsafe, managed code over p/Invoke or JNI is that it allows the programmer to continue to work in the familiar C# environment to accomplish some tasks that otherwise would require calling out to unmanaged code. A program or assembly using unsafe code must be compiled with a special switch and will be marked as such. This enables runtime environments to take special precautions before executing potentially harmful code.

Implementations

JVM

Java is ubiquitous across many disparate operating systems and environments. Numerous JVM implementations exist, some under open source licensing.

Java Webstart and Java applets provide convenient, lightweight and secure means of distributing an application to the desktop, while the efficiency of its bytecode representation, coupled with aggressive Java-specific compression technologies such as pack200, makes Java a very bandwidth-friendly means of distributing applications over a network.

.NET framework and Java Runtime Environment

The .NET Framework is roughly comparable to Java Runtime Environment (JRE). They are not parts of the languages themselves, rather they are libraries to be used by programs which are developed using the languages.

Standardization

C# is defined by ECMA and ISO standards, whereas Java is proprietary, though largely controlled through an open community process.

Usage

Community

Java embraces a more open culture, with many competing vendors for functionality. While this completely solves the problem of vendor lock-in, it adds additional complexity to the language. One must not just be familiar with Java, but also all of the various competing frameworks and different implementation gotchas.

Notwithstanding the existence of Mono, C# has vendor and platform lock-in. This significantly simplifies development, as there is one solution, like it or not.

Java follows a more pure approach to development. Java frameworks tend to have a large number of classes that interact with each other, with many layers of abstraction. This allows for a significant amount of power in the frameworks, but learning a new framework can be difficult, and even the "hello world" of some situations can be quite complex.

C# follows a more pragmatic approach. Simple helper classes are often provided in addition to the nested layers of abstraction; in some cases the abstraction layers are not provided at all.

Popularity and evolution

Java is older than C# and has built up a large and highly active user base, becoming the lingua franca in many modern branches of computer science, particularly areas which involve networking. Java dominates programming courses at high school and college level in the United States, and there are currently many more Java than C# books. Java's maturity and popularity have ensured more third party Java API and libraries (many of them open source) than C#.

By contrast, C# is a relatively new language. Microsoft has studied Java, building on its successes, and changed some aspects of the language to better suit certain types of applications. Over time Java's headstart may become less relevant.

An occasionally voiced criticism of the Java language is that it evolves slowly, lacking some features which make fashionable programming patterns and methodologies easier. An occasionally voiced criticism of the C# language is that its designers are perhaps too quick to pander to current trends in programming - lacking focus and simplicity. Certainly Java's designers seem to have taken a more conservative stand on adding major new features to their language syntax than other current languages - perhaps not wanting to tie the language too tightly with trends which may in the medium/long term be dead ends.

C# has evolved rapidly to attempt to streamline development for problem-specific features. One example in C# 3.0 is the addition of Lambda expressions and extension methods to provide a new model for querying data in the database language SQL and the metadata format XML. Similar language additions to Java have been considered and, for now at least, rejected. This approach, along with a number of other new languages and technologies which address themselves specifically at current programming trends, has sparked a renewed debate within the Java camp about the future direction of the Java language and whether its 'conservative evolution' is right.

Marketplace

Since C#'s inception the two languages have been compared and contrasted. It is undeniable that C# and the CLR (Common Language Runtime) managed code environment in which most C# applications run owe a lot to Java and the JRE (Java Runtime Environment). However C# also accommodates constructs more commonly found in languages such as C++, Delphi (Anders Hejlsberg's principal job when he was at Borland), and scripting languages such as Ruby.

It can be argued that Microsoft developed C# in some part as a result of recognising that the managed code environment which Java champions has many virtues in an increasingly networked world, particularly as the internet moves out onto devices other than personal computers, and security becomes ever more important. Before creating C#, Microsoft modified the Java language (creating "J++") in order to add features for use with the Windows operating system. That effort was eventually blocked by a lawsuit brought by Sun Microsystems, the owner of Java. Unable to produce a flavor of Java with the features it wanted, Microsoft created an alternative which more appropriately suited their own needs and vision of the future.

Despite this fractious start, as time has passed it has become apparent that the two languages rarely compete one-on-one in the marketplace. Java dominates the mobile sector, and has a large following within the web based applications market. C# is very slowly becoming recognised in the desktop market, which is probably Microsoft's desire as they increasingly push towards the use of managed code environments with their operating systems. C# is also a player in the web application market, thanks to Microsoft's .NET framework.

Desktop applications

Java has sometimes been accused of promising much and delivering little when it comes to desktop applications. It is true that although Java's AWT (Abstract Windowing Toolkit) and Swing libraries are not shy of features, Java has struggled to establish a foothold in the desktop market. Its rigid adherence to the notion of write once, run anywhere makes it difficult to use to the maximum the unique features and modes of working within each individual desktop environment.

Sun Microsystems has also been slow, in the eyes of some, to promote Java to developers and end users alike in a way which makes it an appealing choice for desktop software. Even technologies such as Java Web Start, which have few parallels within rival languages and platforms, have barely been promoted.

The release of Java version 6.0, sometime in 2006, sees a renewed focus on the desktop market — with an extensive set of new and interesting tools for better and closer integration with the desktop.

Server applications

This is probably the arena in which the two languages are closest to being considered rivals. Java, through its J2EE (aka JavaEE, Java(2) Enterprise Edition) platform, and C# through .Net, compete to create web based dynamic content and applications.

Both languages are well used and supported in this market, with a bevy of tools and supporting products available for JavaEE and .Net.

However, Java and C# do not directly lock horns in this market, due to the development language usually being a secondary concern (some might even say a side effect) to the choice of operating system or framework. In short, the real rivalry is between Windows and Linux, or IIS and Apache, not Java and C#.

Mobile applications

Java's J2ME (aka JavaME, Java(2) Micro Edition) has a very large base within the mobile phone and PDA markets, with only the cheapest devices now devoid of a KVM (a cut down Java Virtual Machine for use on devices with limited processing power). Java software, including many games, is commonplace.

While almost every mobile phone includes a JVM, these features are not heavily used by most users (particularly in the United States). Java applications on most phones typically consist of menuing systems, small games, or systems to download ringtones etc. Full featured cell phone applications are rare.

In the Smartphone and PDA market, Windows Mobile is gaining ground quickly, and the preferred platform for writing heavy business applications is becoming Windows Mobile, using .NET.


See also