Comparison of C Sharp and Java
Encyclopedia
This article compares Microsoft's
C# programming language with Oracle's
(formerly Sun's
) Java
programming language. While the focus of this article is mainly the programming language
s and their features, such a comparison will necessarily also consider some platform features and some library features. For a more detailed comparison of the platforms, please see Comparison of the Java and .NET platforms
.
The comparison will naturally focus on areas where the languages differ. In fact the two languages and their platforms are more alike than they are different: Both are (primarily) statically, strongly, and mostly manifestly
typed
, both are class-based
object-oriented
, both are designed with semi-interpretation
or runtime compilation
in mind, both use garbage-collection
, and both are "curly brace" languages like C
and C++
. Common ancestry is also evident in their common terminology and often very similar syntax features.
C# supports more features than Java which to some extent is also evident in the syntax which specifies more keywords and more grammar rules than Java.
Java language designers have avoided new keywords as much as possible, preferring instead to introduce new syntactic constructs which were not legal before or to reuse existing keywords in new contexts. This way they didn't jeopardize backward compatibility. An example of the former can be found in how the
C# language designers have introduced several new keywords since the first version. However, instead of defining these keywords as global keywords, they define them as context sensitive keywords. This means that even when they introduced (among others) the
s all derive from a common root type, however. C# has a unified type system
in which all types ultimately derive from a common root type. Consequently, all types implement the methods of this root type, and extension methods defined for the
. Note, that unlike Java, this allows C# to support objects with encapsulation which are not reference types.
In Java compound types are synonymous with reference types; methods cannot be defined for a type unless it is also a class reference type. In C# the concepts of encapsulation and methods have been decoupled from the reference requirement so that a type can support methods and encapsulation without being a reference type. Only reference types support virtual methods and specialization, however.
s, while they are called simple types in C#. The simple/primitive types typically have native support from the underlying processor architecture.
C# has a few more primitive types than Java, because it supports unsigned
as well as signed
integer types, and a
Java lacks the unsigned types. In particular, Java lacks a primitive type for an unsigned byte
. The Java
Both languages feature a native
C# has a type for high-precision (28 decimal digits) decimal arithmetic for e.g. financial and monetary applications. While Java lacks such a built-in type, the Java library does feature an arbitrary precision decimal type. This is not considered a language type and it does not support the usual arithmetic operators; rather it is a reference type which must be manipulated using the type methods. See more about arbitrary size/precision numbers below.
The C# primitive/simple types implement a number of interfaces and consequently offer a number of methods directly on instances of the types - even on the literals. The C# type names are also merely aliases for Common Language Runtime
types. The C#
Java does not offer methods directly on the primitive types. Instead methods which operate on the primitive values are offered through companion wrapper classes
. A fixed set of such wrapper classes exist each of which wraps one of the fixed set of primitive types. As an example, the Java
which wraps the primitive
The following table summarizes the corresponding simple/primitive types of the languages:
types.
Only Java offers a data type for arbitrary precision decimal point
calculations and only C# offers a type for working with complex numbers.
In both languages the number of operations which can be performed are limited compared to the built-in IEEE 754 floating point types. For instance, none of the types support square root
or logarithms.
By using the C# support for type integration through custom operator overloading
and custom (implicit and explicit) type conversions, C# achieves better parity with the built-in types.
s as (immutable
) objects of reference type. In both languages the type contains a number of methods to manipulate strings, parse, format etc. In both languages regular expression
s are considered an external feature and is implemented in separate classes.
Both languages' libraries define classes for working with dates and calendars in different cultures. The Java
s, using the
Because value types have no notion of a null value and can be used in arrays without initialization, they always come with an implicit default constructor that essentially fills the struct memory space with zeroes. The programmer can only define additional constructors with one or more arguments. Value types do not have virtual method table
s, and because of that (and the fixed memory footprint), they are implicitly sealed. However, value types can (and frequently do) implement interfaces. For example, the built-in integer types implement a number of interfaces.
Apart from the built-in primitive types, Java does not include the concept of value types.
In both C# and Java, programmers can use enumerations in a switch statement
without conversion to a string or primitive integer type.
. A delegate is a special type which can capture a type-safe reference to a method. This reference can then be stored in a delegate-type variable or passed to a method through a delegate parameter for later invocation. C# delegates support covariance and contravariance
, and can hold a reference to any signature-compatible static method, instance method, anonymous method or lambda expression
.
Delegates should not be confused with closures and inline functions. The concepts are related because a reference to a closure/inline function must be captured in a delegate reference to be useful at all. But a delegate does not always reference an inline function, it can also reference existing static or instance methods. Delegates form the basis of C# events but should not be confused with those either.
Delegates were deliberately left out of Java because they were considered unnecessary and detrimental to the language, and because of potential performance issues. Instead, an alternative mechanism must be used. The wrapper pattern, which resembles the delegates of C# in that it barely allows the client to access one or more client-defined subroutines through a known interface, is one way to design such a mechanism.
Java does not support type lifting as a concept, but all of the built-in primitive types have corresponding wrapper types, which do support the
According to the Java spec, any attempt to dereference the null reference must result in an exception being thrown at run-time, specifically a NullPointerException. (It would not make sense to dereference it otherwise, because, by definition, it points to no object in memory.) This also applies when attempting to unbox a variable of a wrapper type, which evaluates to null: the program will throw an exception, because actually there is no object to be unboxed - and therefore no boxed value to take part in the subsequent computation.
The following example illustrates the different behavior. In C#, the lifted * operator propagates the
Not all C# lifted operators have been defined to propagate
thus keeping impedance with SQL
.
The Java boolean operators do not support ternary logic, nor is it implemented in the base class library.
dynamic type which supports no-reflection dynamic invocation, interoperability with dynamic languages as well as ad-hoc binding to (for example) document object models. The
There are several use cases for the
Java does not support a late-bound type. The use cases for C# dynamic type have different corresponding constructs in Java:
The C#
with unmanaged APIs or system calls (which are inherently "unsafe"), or for performance reasons.
Java does not permit pointers or pointer-arithmetic within the Java runtime environment and native interop is handled externally through JNI or other mechanisms.
, with syntax similar to C++
(C++ in turn derives from C
). Neither language is a superset of C or C++, however.
Both languages mainly use garbage collection
as a means of reclaiming memory resources, rather than explicit deallocation of memory. In both cases, if an object holds resources of different kinds other than memory, such as file handles, graphical resources, etc., then it will have to be notified explicitly when the application no longer uses it. Both C# and Java offer interfaces for such deterministic disposal and both C# and Java (since Java 7) feature automatic resource management statements which will automatically invoke the disposal/close methods on those interfaces.
Both languages include thread synchronization
mechanisms as part of their language syntax.
C# initializes object fields in the following order when creating an object:
Some of the above fields may not be applicable (e.g. if an object does not have static fields). Derived fields are those that are defined in the object's direct class, while base field is a term for the fields that are defined in one of the object's superclasses. Note that an object representation in memory contains all fields defined in its class or any of its superclasses, even if some fields in superclasses are defined as private.
It is guaranteed that any field initializers take effect before any constructors are called, since both the instance constructor of the object's class and its superclasses are called after field initializers are called. There is, however, a potential trap in object initialization when a virtual method is called from a base constructor. The overridden method in a subclass may reference a field that is defined in the subclass, but this field may not have been initialized because the constructor of the subclass that contains field initialization is called after the constructor of its base class.
In Java, the order of initialization is as follows:
Like in C#, a new object is created by calling a specific constructor. Within a constructor, the first statement may be an invocation of another constructor. If this is omitted, the call to the argumentless constructor of the superclass is added implicitly by the compiler. Otherwise, either another overloaded constructor of the object's class can be called explicitly, or a superclass constructor can be called. In the former case, the called constructor will again call another constructor (either of the object's class or its subclass) and the chain sooner or later ends up at the call to one of the constructors of the superclass.
After another constructor is called (which causes direct invocation of the superclass constructor, and so forth, down to the Object class), instance variables defined in the object's class are initialized. Even if there are no variable initializers explicitly defined for some variables, these variables are initialized to default values. Note that instance variables defined in superclasses are already initialized by this point, because they were initialized by a superclass constructor when it was called (either by the constructor's code or by variable initializers performed before the constructor's code or implicitly to default values). In Java, variable initializers are executed according to their textual order in the source file.
Finally, the constructor body is executed. This ensures proper order of initialization, i.e. the fields of a base class finish initialization before initialization of the fields of an object class begins.
There are two main potential traps in Java's object initialization. First, variable initializers are expressions that can contain method calls. Since methods can reference any variable defined in the class, the method called in a variable initializer can reference a variable that is defined below the variable being initialized. Since initialization order corresponds to textual order of variable definitions, such a variable would not be initialized to the value prescribed by its initializer and would contain the default value.
Another potential trap is when a method that is overridden in the derived class is called in the base class constructor, which can lead to behavior the programmer would not expect when an object of the derived class is created. According to the initialization order, the body of the base class constructor is executed before variable initializers are evaluated and before the body of the derived class constructor is executed. The overridden method called from the base class constructor can, however, reference variables defined in the derived class, but these are not yet initialized to the values specified by their initializers or set in the derived class constructor. The latter issue applies to C# as well, but in a less critical form since in C# methods are not overridable by default.
are concepts featured by both languages. The syntax used to declare and access arrays is identical, except that C# has added syntax for declaring and manipulating multidimensional arrays.
Multidimensional arrays can in some cases increase performance because of increased locality (as there is a single pointer dereference, instead of one for every dimension of the array as is the case for jagged arrays). However, since all array element access in a multidimensional array requires multiplication/shift between the two or more dimensions, this is an advantage only in very random access scenarios.
Another potential advantage is that the entire multidimensional array can be allocated with a single application of operator
Both languages feature an extensive set of collection types which includes various ordered and unordered types of lists, maps/dictionaries, sets, etc.
and user-defined casts
are separate features which both aim to allow new types to become first-class citizens in the type system. By using these features in C#, types such as
Java does not include operator overloading nor custom conversions in order to prevent abuse of the feature, and to keep the language simple.
Java does not include indexers. The common Java pattern involves writing explicit getters and setters where a C# programmer would use an indexer.
design) where a code generator can supply one part and the developer another part to be compiled together. The developer can thus edit their part without the risk of a code generator overwriting that code at some later time. Unlike the class extension mechanism, a partial class allows "circular" dependencies among its parts as they are guaranteed to be resolved at compile time. Java has no corresponding concept.
In Java, unless the inner class is declared
In C#, an inner class is conceptually the same as a normal class. In a sense, the outer class only acts as a namespace. Thus, code in the inner class cannot access non-static members of the outer class unless it does so through an explicit reference to an instance of the outer class. Programmers can declare the inner class private to allow only the outer class to have any access to it.
Java provides another feature called local classes or anonymous classes, which can be defined within a method body. These are generally used to implement an interface with only one or two methods, which are typically event handlers. However, they can also be used to override virtual methods of a superclass. The methods in those local classes have access to the outer method's local variables declared
; see event handling for more about this.
C# also provides a feature called anonymous types/classes, but it is rather different from Java's concept with the same name. It allows the programmer to instantiate a class by providing only a set of names for the properties the class should have, and an expression to initialize each. The types of the properties are inferred from the types of those expressions. These implicitly-declared classes are derived directly from object.
, separate to its own class methods, or to provide different implementations for two methods with the same name and signature inherited from two base interfaces.
and is an implementation of the observer pattern
. To support this there is a specific syntax to define events in classes, and operators to register, unregister or combine event handlers.
See here for information about how events are implemented in Java.
In C#, the primitive types are subtypes of the Object type. In Java this is not true; any given primitive type and the corresponding wrapper type have no specific relationship with each other, except for autoboxing and unboxing, which act as syntactic sugar
for interchanging between them. This was done intentionally, to maintain backward compatibility with prior versions of Java, in which no automatic casting was allowed, and the programmer worked with two separate sets of types: the primitive types, and the wrapper (reference) type hierarchy.
This difference has the following consequences. First of all, in C#, primitive types can define methods, such as an override of Object's
es.
Secondly, in Java an extra cast is needed whenever one tries to directly dereference
a primitive value, as it will not be boxed automatically. The expression
Finally, another difference is that Java makes heavy use of boxed types in generics
(see below).
the two languages show a superficial syntactical similarity, but they have deep underlying differences.
are a language-only construction; they are implemented only in the compiler. The generated classfiles include generic signatures only in the form of metadata (allowing the compiler to compile new classes against them). The runtime has no knowledge of the generic type system; generics are not part of the JVM. Instead, generics classes and methods are transformed during compilation through a process known as type erasure
. During this process the compiler replaces all generic types with their raw version and inserts casts/checks appropriately in client code where the type and its methods are used. The resulting byte code will contain no references to any generic types or parameters (See also Generics in Java
).
The language specification intentionally prohibits certain uses of generics; this is necessary to allow for implementing generics through type erasure
, and to allow for migration compatibility.
C# builds on support for generics from the virtual execution system itself, i.e. it is not just a language feature. The language is merely a front-end for cross-language generics support in the CLR
. During compilation generics are verified for correctness, but code generation for actually implementing the generics are deferred to class-load time. Client code (code invoking generic methods/properties) are fully compiled and can safely assume generics to be type-safe. This is called reification
. At runtime, when a unique set of type parameters for a generic class/method/delegate is encountered for the first time, the class loader/verifier will synthesize a concrete class descriptor and generate method implementations. During the generation of method implementations all reference types will be considered a single type, as reference types can safely share the same implementations. Note, this is merely for the purpose of the implementing code. Different sets of reference types will still have unique type descriptors; their method tables will merely point to the same code.
The following list illustrates some differences between Java and C# when managing generics. It is not exhaustive:
C# allows generics directly for primitive types. Java, instead, allows the use of boxed types as type parameters (e.g.,
. In particular, the original requirement was "... there should be a clean, demonstrable migration path for the Collections APIs that were introduced in the Java 2 platform". This was designed so that any new generic collections should be passable to methods which expected one of the pre-existing collection classes.
C# generics were introduced into the language while preserving full backward compatibility, but did not preserve full migration compatibility: Old code (pre C# 2.0) runs unchanged on the new generics-aware runtime without recompilation. As for migration compatibility, new generic collection classes and interfaces were developed which supplemented the non-generic .NET 1.x collections rather than replacing them. In addition to generic collection interfaces, the new generic collection classes implement the non-generic collection interfaces where possible. This prevents the use of new generic collections with pre-existing (non-generic aware) methods, if those methods are coded to use the collection classes.
keyword, which enables strict floating-point calculations for a region of code. This will ensure that calculations return exactly the same result on all platforms. C# provides no equivalent, but does provide the built-in
The class also provides such characteristics for Java.
In Java there is no way to provide the same level of integration for library-defined types such as
s as there is for the primitive types. For this purpose, C# provides the following:
In addition to this, C# can help mathematical applications with the
for a region of code.
by default, and have to be declared virtual explicitly if desired. In Java, all non-static non-private methods are virtual. Virtuality guarantees that the most recent override
for the method will always be called, but incurs a certain runtime cost on invocation as these invocations cannot be normally inlined
, and require an indirect call via the virtual method table
. However, some JVM implementations, including the Sun reference implementation, implement inlining of the most commonly called virtual methods.
Java methods are virtual by default (although they can be "sealed" by using the
This means that by default in Java, and only when explicitly enabled in C#, new methods may be defined in a derived class with the same name and signature as those in its base class. When the method is called on a superclass reference of such an object, the "deepest" overridden implementation of the base class' method will be called according to the specific subclass of the object being referenced.
In some cases, when a subclass introduces a method with the same name and signature as a method already present in the base class, problems can occur. In Java, this will mean that the method in the derived class will implicitly override the method in the base class, even though that may not be the intent of the designers of either class.
To mitigate this, C# requires that if a method should be overridden, the
Java does not have an equivalent feature. Instead generators are typically defined by providing a specialized implementation of a well-known collection or iterable interface, which will compute each element on demand. For such a generator to be used in a for each statement, it must implement interface
Below these two approaches are shown for the two languages. Both use the designated iterator/enumerator interface of the language. Note how the C# version use multiple
C# supports closures as anonymous methods or lambda expressions with full-featured closure
semantics.
In Java, anonymous inner classes remains the preferred way to emulate closures. Aside from being a more verbose construction, this approach also has some drawbacks compared to real closures, such as limited access to variables from the enclosing scopes (only final members can be referenced).
When a reference to a method can be passed around for later execution, a problem arises about what to do when the method has references to variables/parameters in its lexical scope. C# closures can fully capture any variable/parameter from its lexical scope. In Java's anonymous inner classes only references to final members of the lexical scope are allowed, thus requiring the developer to artificially introduce extra levels of indirections and boxing primitive types if he wants to reference and update those from the inner class.
While Java does not currently feature closures, it has been announced that some form of closures or lambdas will be included in JDK 8 which at latest update (10 October 2010) is scheduled for release "late 2012".
is not really a single feature; rather it is a number of features designed to work together to allow for in-language querying capabilities. LINQ has emerged as one of the most distinguishing features between Java and C#.
LINQ consists of the following features:
s called lambdas. These are anonymous methods: they have a signature and a body, but no name. They are mainly used to specify local function-valued arguments in calls to other methods, a technique mainly associated with functional programming
. On top of that, lambda functions can double as a way to define special data structures called expression trees. Whether they are seen as an executable function or as a data structure depends on compiler type inference and what type of variable or parameter they are assigned or cast to. Lambdas and expression trees play key roles in LINQ
. Java does not feature lambdas or expression trees; its primary mechanism for inline scope capture and method definition is the anonymous inner class syntax.
GoF
design pattern) without paying any runtime overhead if these extension points are not being used by another class part at compile time. Java has no corresponding concept.
using preprocessor directives. It also provides a
to define methods that are only called when a given compilation constant is defined. This way, assertions
can be provided as a framework feature with the method
s are similar to those in C++
. Unlike package
names in Java, a namespace is not in any way tied to the location of the source file. While it is not strictly necessary for a Java source file location to mirror its package directory structure, it is the conventional organization.
Both languages allow importing of classes (e.g.,
Java has a static import
syntax that allows using the short name of some or all of the static methods/fields in a class (e.g., allowing
s to allow users to statically add a method to a type (e.g., allowing
The Sun Microsystems
Java compiler requires that a source file name must match the only public class inside it, while C# allows multiple public classes in the same file, and puts no restrictions on the file name. C# 2.0 and later allows splitting a class definition into several files by using the
Checked exceptions can encourage good programming practice, ensuring that all errors are dealt with. However Anders Hejlsberg
, chief C# language architect, argues that they were to some extent an experiment in Java and that they have not been shown to be worthwhile except in small example programs.
One criticism is that checked exceptions encourage programmers to use an empty catch block (
can be applied instead, by re-throwing the exception in a wrapper exception. For example, if an object is changed to access a database instead of a file, an could be caught and re-thrown as an , since the caller may not need to know the inner workings of the object.
There are also differences between the two languages in treating the
A common reason for using
A rather subtle difference is the moment a stack trace is created when an exception is being thrown. In Java, the stack trace is created in the moment the exception is created.
The exception in the statement above will always contain the constructor's stack-trace - no matter how often foo is called.
In C# on the other hand, the stack-trace is created the moment "throw" is executed.
In the code above, the exception will contain the stack-trace of the first throw-line. When catching an exception, there are two options in case the exception should be rethrown:
In the above code, the
C# does not allow any statements which allow control flow to leave the
(JNI) feature allows Java programs to call non-Java code. However, JNI does require the code being called to follow several conventions and imposes 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++. Java Native Access
(JNA) allows easier calling of native code that only requires writing Java code, but comes at a performance cost.
In addition, third party libraries provide for Java-COM
bridging, e.g. JACOB (free
), and J-Integra for COM (proprietary
).
.NET Platform Invoke (P/Invoke
) offers the same capability by allowing calls from C# 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. P/Invoke allows almost complete access to procedural APIs (such as Win32 or POSIX), but limited access to C++ class libraries.
In addition, .NET Framework also provides a .NET-COM bridge, allowing access to COM components as if they were native .NET objects.
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 using this feature, the programmer must mark the code using the
(JVM) as well as a common set of libraries. The JRE was originally designed to support interpreted execution with final compilation as an option. Most JRE environments execute fully or at least partially compiled programs, possibly with adaptive optimization
. The Java compiler produces Java bytecode
. Upon execution the bytecode is loaded by the Java runtime and either interpreted directly or compiled to machine instructions and then executed.
C# is designed to execute on the Common Language Runtime
(CLR). The CLR is designed to execute fully compiled code. The C# compiler produces Common Intermediate Language
instructions. Upon execution the runtime loads this code and compiles to machine instructions on the target architecture.
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 more Java books than C# books. Java's maturity and popularity have ensured more third party Java APIs and libraries (many of them open source) than C#.
An occasionally voiced criticism of the Java language is that it evolves slowly, lacking some features which make fashionable programming patterns and methodologies easier. Some critics suggest that the designers of C# may pander too quickly to current trends in programming, thus lacking focus and simplicity. 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 prove to be dead ends.
These trends have been broken with the Java 5.0 release, which introduced several new major language features: a foreach
construct, autoboxing, methods with variable number of parameters (varargs), enumerated type
s, generic types
, and annotation
s. With the exception of Generics, C# included all these features from its beginning, some under different names. Proposals and specifications for the new features had been worked on in the Java community for a considerable time before they were introduced. Indeed, some had been in gestation since before C#'s initial release (e.g., work on Generics formally began in May 1999), such was the Java community's conservatism at that time.
Problem-specific 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 that address themselves specifically toward 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.
As of 2008 debate continued over the inclusion of closures
and properties
into the language syntax for Java 7.
, Delphi (the design of which was Anders Hejlsberg's
principal job when he was at Borland
), and, in recent C# versions, borrows from dynamic scripting languages such as Ruby and Python.
C# 3.0 adds SQL
-like language integrated queries
suited for querying data from collections, database
s or XML
documents, building upon general-purpose language features, including lambda expression
s and extension method
s, to allow queries to be expressed and optimized for user types.
Before creating C#, Microsoft implemented a modified Java environment, called J++
, adding new features in a manner which was in direct contravention to the standards and conventions that ensure the platform neutrality which lies at the heart of Java. This violated the license agreement Microsoft had signed, requiring that standards and specifications be strictly adhered to in return for using the Java name and brand logos. Sun Microsystems sued, and in settling the suit, Microsoft agreed to discontinue J++. (The settlement allowed other existing Java-using Microsoft products to continue such use for seven years.) With the release of the .NET framework (and C#), the project was revived in the form of J#
.
Microsoft
Microsoft Corporation is an American public multinational corporation headquartered in Redmond, Washington, USA that develops, manufactures, licenses, and supports a wide range of products and services predominantly related to computing through its various product divisions...
C# programming language with Oracle's
Oracle Corporation
Oracle Corporation is an American multinational computer technology corporation that specializes in developing and marketing hardware systems and enterprise software products – particularly database management systems...
(formerly Sun's
Sun Microsystems
Sun Microsystems, Inc. was a company that sold :computers, computer components, :computer software, and :information technology services. Sun was founded on February 24, 1982...
) Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
programming language. While the focus of this article is mainly the programming language
Programming language
A programming language is an artificial language designed to communicate instructions to a machine, particularly a computer. Programming languages can be used to create programs that control the behavior of a machine and/or to express algorithms precisely....
s and their features, such a comparison will necessarily also consider some platform features and some library features. For a more detailed comparison of the platforms, please see Comparison of the Java and .NET platforms
Comparison of the Java and .NET platforms
- Standardization :The two platforms, their programming libraries, their binary formats, and their runtime environments have largely been governed by very different means.The .NET platform as a whole has not been standardized...
.
The comparison will naturally focus on areas where the languages differ. In fact the two languages and their platforms are more alike than they are different: Both are (primarily) statically, strongly, and mostly manifestly
Manifest typing
In computer science, manifest typing is when the software programmer explicitly identifies the type of each variable being declared. For example: if variable X is going to store integers then its type must be declared as integer....
typed
Type system
A type system associates a type with each computed value. By examining the flow of these values, a type system attempts to ensure or prove that no type errors can occur...
, both are class-based
Class (computer science)
In object-oriented programming, a class is a construct that is used as a blueprint to create instances of itself – referred to as class instances, class objects, instance objects or simply objects. A class defines constituent members which enable these class instances to have state and behavior...
object-oriented
Object-oriented programming
Object-oriented programming is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs. Programming techniques may include features such as data abstraction,...
, both are designed with semi-interpretation
Interpreter (computing)
In computer science, an interpreter normally means a computer program that executes, i.e. performs, instructions written in a programming language...
or runtime compilation
Just-in-time compilation
In computing, just-in-time compilation , also known as dynamic translation, is a method to improve the runtime performance of computer programs. Historically, computer programs had two modes of runtime operation, either interpreted or static compilation...
in mind, both use garbage-collection
Garbage collection (computer science)
In computer science, garbage collection is a form of automatic memory management. The garbage collector, or just collector, attempts to reclaim garbage, or memory occupied by objects that are no longer in use by the program...
, and both are "curly brace" languages like C
C (programming language)
C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system....
and C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
. Common ancestry is also evident in their common terminology and often very similar syntax features.
Feature comparison
This section provides a comparison of the languages in terms of features they may or may not offer, or, put differently, properties they may or may not have. The absence of a feature should not automatically be regarded as a disadvantage for the given language; sometimes features may be excluded because the language designers view them as specifically detrimental, and in other cases the designers may have viewed the feature as something that would be nice to have but not worth the added language complexity.Data types | |Java | |C# |
---|---|---|
Single-root (unified) type system | ||
Signed integers Signedness In computing, signedness is a property of data types representing numbers in computer programs. A numeric variable is signed if it can represent both positive and negative numbers, and unsigned if it can only represent non-negative numbers .As signed numbers can represent negative numbers, they... |
; 8, 16, 32, 64 bits | ; 8, 16, 32, 64 bits |
Unsigned integers | ; 8, 16, 32, 64 bits | |
Character | ||
Date/time | ; reference type | ; value type |
IEEE 754 binary32 floating point number | ||
IEEE 754 binary64 floating point number | ||
High precision floating point number | ||
Boolean type | ||
Strings | ||
Arbitrary size integers | ||
Arbitrary size decimals | ||
Complex numbers | ||
Reference types | ||
Arrays | ||
Value types | ; only primitive types | |
Enumerated types | ; reference type | ; scalar |
Lifted (nullable) types | ; but wrapper types | |
Tuples | ||
Pointers |
Reference types | |Java | |C# |
---|---|---|
Garbage collection Garbage collection (computer science) In computer science, garbage collection is a form of automatic memory management. The garbage collector, or just collector, attempts to reclaim garbage, or memory occupied by objects that are no longer in use by the program... |
||
Weak reference Weak reference In computer programming, a weak reference is a reference that does not protect the referenced object from collection by a garbage collector . An object referenced only by weak references is considered unreachable and so may be collected at any time... s |
||
Soft reference Soft reference A soft reference is one of the strengths or levels of 'non strong' reference defined in the Java programming language, the others being weak and phantom.... s |
||
Proxy support Proxy pattern In computer programming, the proxy pattern is a software design pattern.A proxy, in its most general form, is a class functioning as an interface to something else... |
; proxy generation | ; object contexts |
Object orientation | |Java | |C# |
---|---|---|
Classes Class (computer science) In object-oriented programming, a class is a construct that is used as a blueprint to create instances of itself – referred to as class instances, class objects, instance objects or simply objects. A class defines constituent members which enable these class instances to have state and behavior... |
||
Interfaces Interface (computer science) In the field of computer science, an interface is a tool and concept that refers to a point of interaction between components, and is applicable at the level of both hardware and software... |
||
Abstract classes | ||
Member accessibility levels | ||
Class-level inner classes | ||
Instance-level inner classes | ||
Partial classes | ||
Statement-level anonymous classes | ||
Implicit (inferred) anonymous classes | ||
Deprecation Deprecation In the process of authoring computer software, its standards or documentation, deprecation is a status applied to software features to indicate that they should be avoided, typically because they have been superseded... /obsolescence |
||
Overload versioning | ||
Properties Property (programming) A property, in some object-oriented programming languages, is a special sort of class member, intermediate between a field and a method. Properties are read and written like fields, but property reads and writes are translated to get and set method calls... |
, but see JavaBeans JavaBeans JavaBeans are reusable software components for Java. Practically, they are classes written in the Java programming language conforming to a particular convention. They are used to encapsulate many objects into a single object , so that they can be passed around as a single bean object instead of as... spec |
|
Events Event (computing) In computing an event is an action that is usually initiated outside the scope of a program and that is handled by a piece of code inside the program. Typically events are handled synchronous with the program flow, that is, the program has one or more dedicated places where events are handled... |
; but the base class library does feature an event mechanism | |
Operator overloading Operator overloading In object oriented computer programming, operator overloading—less commonly known as operator ad-hoc polymorphism—is a specific case of polymorphism, where different operators have different implementations depending on their arguments... |
||
Indexers | ||
Implicit conversions | ||
Explicit conversions |
Fields and initialization | |Java | |C# |
---|---|---|
Fields Field (computer science) In computer science, data that has several parts can be divided into fields. Relational databases arrange data as sets of database records, also called rows. Each record consists of several fields; the fields of all records form the columns.... |
||
Constants Constant (programming) In computer programming, a constant is an identifier whose associated value cannot typically be altered by the program during its execution... |
||
Static (class) constructors | ||
Instance constructors | ||
Finalizers/destructors Destructor (computer science) In object-oriented programming, a destructor is a method which is automatically invoked when the object is destroyed... |
||
Instance initializers | ||
Object initialization Initialization (programming) In computer programming, initialization is the assignment of an initial value for a data object or variable. The manner in which initialization is performed depends on programming language, as well as type, storage class, etc., of an object to be initialized. Programming constructs which perform... |
||
Object initializers | ||
Collection initializers | ; can be modelled | |
Array initializers |
Methods and properties | |Java | |C# |
---|---|---|
Static imports | ||
Virtual | ||
Abstract Abstraction (computer science) In computer science, abstraction is the process by which data and programs are defined with a representation similar to its pictorial meaning as rooted in the more complex realm of human life and language with their higher need of summarization and categorization , while hiding away the... |
||
Sealing | ||
Explicit interface implementation | ||
Value (input) parameters | ||
Reference (input/output) parameters | ||
Output (output) parameters | ||
Variadic methods Variadic function In computer programming, a variadic function is a function of indefinite arity, i.e., one which accepts a variable number of arguments. Support for variadic functions differs widely among programming languages.... |
||
Optional arguments | ||
Named arguments | ||
Generator methods | ||
Extension methods | ||
Conditional methods | ||
Partial methods |
Generics | |Java | |C# |
---|---|---|
Reified generics Reification (computer science) Reification is the process by which an abstract idea about a computer program is turned into an explicit data model or other object created in a programming language. A computable/addressable object — a resource — is created in a system as a proxy for a non computable/addressable object... |
||
Runtime realization | ||
Covariance Covariance and contravariance (computer science) Within the type system of a programming language, covariance and contravariance refers to the ordering of types from narrower to wider and their interchangeability or equivalence in certain situations .... |
||
Contravariance Covariance and contravariance (computer science) Within the type system of a programming language, covariance and contravariance refers to the ordering of types from narrower to wider and their interchangeability or equivalence in certain situations .... |
||
Reference type constraint | ; implicit | |
Value/primitive type constraint | ||
Constructor constraint | ||
Relation constraint | ||
Primitive/value type support | ||
Migration compatibility |
Functional programming | |Java | |C# |
---|---|---|
Method references | ; but see Delegates / method references | |
Closures/lambdas Closure (computer science) In computer science, a closure is a function together with a referencing environment for the non-local variables of that function. A closure allows a function to access variables outside its typical scope. Such a function is said to be "closed over" its free variables... |
; but see Delegates / method references | |
Expression trees Abstract syntax tree In computer science, an abstract syntax tree , or just syntax tree, is a tree representation of the abstract syntactic structure of source code written in a programming language. Each node of the tree denotes a construct occurring in the source code. The syntax is 'abstract' in the sense that it... |
||
Generic query language |
Runtime (dynamic) binding | |Java | |C# |
---|---|---|
Late-bound (dynamic) type |
Runtime type information and manipulation | |Java | |C# |
---|---|---|
Runtime type information | ; but with type erasure | |
Runtime generics realization | ||
Runtime type construction | ; third party tools exist |
Statements | |Java | |C# |
---|---|---|
Loops | ||
Conditionals | ||
Flow control | ||
Assignment Assignment (computer science) In computer programming, an assignment statement sets or re-sets the value stored in the storage location denoted by a variable name. In most imperative computer programming languages, assignment statements are one of the basic statements... |
||
Exception control | ||
Variable declaration | ||
Variable type inference | ||
Deterministic disposal (ARM-blocks) | (starting with Java 7) |
Expressions and operators | |Java | |C# |
---|---|---|
Arithmetic operators | ||
Logical operators | ||
Bitwise logic operators | ||
Conditional | ||
String concatenation | ||
Casts | ||
Boxing | ; implicit | ; implicit |
Unboxing | ; implicit | ; explicit |
Lifted operators | ||
Overflow control | ||
Strict floating point evaluation | ; opt-in/out | |
Verbatim (here-)strings |
Exceptions | |Java | |C# |
---|---|---|
Checked exceptions | ||
Try-catch-finally |
Arrays Array data type In computer science, an array type is a data type that is meant to describe a collection of elements , each selected by one or more indices that can be computed at run time by the program. Such a collection is usually called an array variable, array value, or simply array... and Collections Collection (computing) In computer science, a collection is a grouping of some variable number of data items that have some shared significance to the problem being solved and need to be operated upon together in some controlled fashion. Generally, the data items will be of the same type or, in languages supporting... | |Java | |C# |
---|---|---|
Abstract data type Abstract data type In computing, an abstract data type is a mathematical model for a certain class of data structures that have similar behavior; or for certain data types of one or more programming languages that have similar semantics... s |
||
One-dimensional, zero-based index arrays | ||
Rectangular (multidimensional) arrays | ||
Jagged (arrays of arrays) arrays | ||
Non-zero based arrays | ||
Unified arrays and collections | ||
Maps/dictionaries Associative array In computer science, an associative array is an abstract data type composed of a collection of pairs, such that each possible key appears at most once in the collection.... |
||
Sorted dictionaries | ||
Sets | ||
Sorted sets | ||
Lists/vectors | ||
Queues/stacks | ||
Priority queue Priority queue A priority queue is an abstract data type in computer programming.It is exactly like a regular queue or stack data structure, but additionally, each element is associated with a "priority".... |
||
Bags/multisets |
Metadata Metadata The term metadata is an ambiguous term which is used for two fundamentally different concepts . Although the expression "data about data" is often used, it does not apply to both in the same way. Structural metadata, the design and specification of data structures, cannot be about data, because at... | |Java | |C# |
---|---|---|
Metadata annotations/attributes | ||
Positional arguments | ; unless a single argument | |
Named arguments | ||
Default values | ||
Nested types | ||
Specialization | ||
Conditional metadata |
Preprocessing Preprocessor In computer science, a preprocessor is a program that processes its input data to produce output that is used as input to another program. The output is said to be a preprocessed form of the input data, which is often used by some subsequent programs like compilers... , Compilation Compiler A compiler is a computer program that transforms source code written in a programming language into another computer language... and Packaging Modular programming Modular programming is a software design technique that increases the extent to which software is composed of separate, interchangeable components called modules by breaking down program functions into modules, each of which accomplishes one function and contains everything necessary to accomplish... | |Java | |C# |
---|---|---|
Namespaces Namespace (computer science) A namespace is an abstract container or environment created to hold a logical grouping of unique identifiers or symbols . An identifier defined in a namespace is associated only with that namespace. The same identifier can be independently defined in multiple namespaces... |
||
Packaging | ||
Classes/assembly search path | ; ClassPath | ; /lib |
File contents | ||
Conditional compilation | ||
Custom errors/warnings | ||
Explicit regions |
Threading Thread (computer science) In computer science, a thread of execution is the smallest unit of processing that can be scheduled by an operating system. The implementation of threads and processes differs from one operating system to another, but in most cases, a thread is contained inside a process... and Synchronization Synchronization (computer science) In computer science, synchronization refers to one of two distinct but related concepts: synchronization of processes, and synchronization of data. Process synchronization refers to the idea that multiple processes are to join up or handshake at a certain point, so as to reach an agreement or... | |Java | |C# |
---|---|---|
Threads | ||
Thread pool Thread pool pattern In computer programming, the thread pool pattern is where a number of threads are created to perform a number of tasks, which are usually organized in a queue. Typically, there are many more tasks than threads. As soon as a thread completes its task, it will request the next task from the queue... |
||
Task-based parallelism | ||
Semaphores Semaphore (programming) In computer science, a semaphore is a variable or abstract data type that provides a simple but useful abstraction for controlling access by multiple processes to a common resource in a parallel programming environment.... |
||
Monitors Monitor (synchronization) In concurrent programming, a monitor is an object or module intended to be used safely by more than one thread. The defining characteristic of a monitor is that its methods are executed with mutual exclusion. That is, at each point in time, at most one thread may be executing any of its methods... |
||
Thread local variables | ; ThreadStaticAttribute |
Native interoperability | |Java | |C# |
---|---|---|
External/native methods | ||
Marshalling | ; metadata controlled | |
Pointers and arithmetics | ||
Native types | ||
Fixed-size buffers | ||
Explicit stack allocation | ||
Address-of | ||
Object pinning (fix variable to address) |
Platform support | |Java | |C# |
---|---|---|
Linux Linux Linux is a Unix-like computer operating system assembled under the model of free and open source software development and distribution. The defining component of any Linux system is the Linux kernel, an operating system kernel first released October 5, 1991 by Linus Torvalds... |
||
Mac OS X Mac OS X Mac OS X is a series of Unix-based operating systems and graphical user interfaces developed, marketed, and sold by Apple Inc. Since 2002, has been included with all new Macintosh computer systems... |
||
Solaris | ||
FreeBSD FreeBSD FreeBSD is a free Unix-like operating system descended from AT&T UNIX via BSD UNIX. Although for legal reasons FreeBSD cannot be called “UNIX”, as the direct descendant of BSD UNIX , FreeBSD’s internals and system APIs are UNIX-compliant... |
||
AIX | ? | |
iOS | ||
Windows Microsoft Windows Microsoft Windows is a series of operating systems produced by Microsoft.Microsoft introduced an operating environment named Windows on November 20, 1985 as an add-on to MS-DOS in response to the growing interest in graphical user interfaces . Microsoft Windows came to dominate the world's personal... |
||
Windows Mobile Windows Mobile Windows Mobile is a mobile operating system developed by Microsoft that was used in smartphones and Pocket PCs, but by 2011 was rarely supplied on new phones. The last version is "Windows Mobile 6.5.5"; it is superseded by Windows Phone, which does not run Windows Mobile software.Windows Mobile is... |
||
Windows Phone Windows Phone Windows Phone is a mobile operating system developed by Microsoft, and is the successor to its Windows Mobile platform, although incompatible with it. Unlike its predecessor, it is primarily aimed at the consumer market rather than the enterprise market... |
||
Android | ||
Feature phones | ||
Symbian Symbian Symbian is a mobile operating system and computing platform designed for smartphones and currently maintained by Accenture. The Symbian platform is the successor to Symbian OS and Nokia Series 60; unlike Symbian OS, which needed an additional user interface system, Symbian includes a user... |
||
Blackberry BlackBerry OS BlackBerry OS is a proprietary mobile operating system, developed by Research In Motion for its BlackBerry line of smartphone handheld devices... |
||
Syntax
Both languages are considered "curly brace" languages in the C/C++ family. Overall the syntaxes of the languages are very similar. The syntax at the statement and expression level is almost identical with obvious inspiration from the C/C++ tradition. At type definition level (classes and interfaces) some minor differences exists. Java is explicit about extending classes and implementing interfaces, while C# infers this from the kind of types a new class/interface derives from.C# supports more features than Java which to some extent is also evident in the syntax which specifies more keywords and more grammar rules than Java.
Keywords and backward compatibility
As the languages evolved, the language designers for both languages have faced situations where they wanted to extend the languages with new keywords and/or syntax. New keywords in particular may break existing code at source level, i.e. older code may no longer compile if presented to a compiler for a later version of the language. Language designers are keen to avoid such regressions. The designers of the two languages have been following different paths when addressing this problem.Java language designers have avoided new keywords as much as possible, preferring instead to introduce new syntactic constructs which were not legal before or to reuse existing keywords in new contexts. This way they didn't jeopardize backward compatibility. An example of the former can be found in how the
for
loop was extended to accept iterable types. An example of the latter can be found in how the extends
and (especially) the super
keywords were reused for specifying type bounds when generics were introduced in Java 1.5. At one time (Java 1.4) a new keyword assert
was introduced which was not reserved as a keyword before. This had the potential to render previously valid code invalid, if for instance the code used assert
as an identifier. The designers chose to address this problem with a 4 step solution: 1) Introducing a compiler switch which indicates if Java 1.4 or later should be used, 2) Only marking assert
as a keyword when compiling as Java 1.4 and later, 3) Defaulting to 1.3 to avoid rendering previous (non 1.4 aware code) invalid and 4) Issue warnings if the keyword is used in Java 1.3 mode, in order to allow the developers to change the code. Thus, the present Java syntax is backward compatible with all previous versions except for the specific case of assert.C# language designers have introduced several new keywords since the first version. However, instead of defining these keywords as global keywords, they define them as context sensitive keywords. This means that even when they introduced (among others) the
partial
and yield
keywords in C# 2.0, the use of those words as identifiers is still valid as there is no clash possible between the use as keyword and the use as identifier, given the context. Thus, the present C# syntax is fully backward compatible with source code written for any previous version without specifying the language version to be used.Type system
The languages use very similar type systems. Both languages are statically typed with class-based object orientation.Unified type system
In Java the primitive types are special in that they are not object-oriented and they could not have been defined using the language itself. They also do not share a common ancestor with reference types. The Java reference typeReference type
In programming language theory, a reference type is a data type that can only be accessed by references. Unlike objects of value types, objects of reference types cannot be directly embedded into composite objects and are always dynamically allocated...
s all derive from a common root type, however. C# has a unified type system
Type system
A type system associates a type with each computed value. By examining the flow of these values, a type system attempts to ensure or prove that no type errors can occur...
in which all types ultimately derive from a common root type. Consequently, all types implement the methods of this root type, and extension methods defined for the
object
type apply to all types, even primitive int
literals and delegatesDelegate (.NET)
A delegate is a form of type-safe function pointer used by the .NET Framework. Delegates specify a method to call and optionally an object to call the method on. They are used, among other things, to implement callbacks and event listeners....
. Note, that unlike Java, this allows C# to support objects with encapsulation which are not reference types.
In Java compound types are synonymous with reference types; methods cannot be defined for a type unless it is also a class reference type. In C# the concepts of encapsulation and methods have been decoupled from the reference requirement so that a type can support methods and encapsulation without being a reference type. Only reference types support virtual methods and specialization, however.
Simple/primitive types
Both languages support a number of built-in types which are copied and passed by value rather than by reference. Java calls these types primitive typePrimitive type
In computer science, primitive data type is either of the following:* a basic type is a data type provided by a programming language as a basic building block...
s, while they are called simple types in C#. The simple/primitive types typically have native support from the underlying processor architecture.
C# has a few more primitive types than Java, because it supports unsigned
Signedness
In computing, signedness is a property of data types representing numbers in computer programs. A numeric variable is signed if it can represent both positive and negative numbers, and unsigned if it can only represent non-negative numbers .As signed numbers can represent negative numbers, they...
as well as signed
Signedness
In computing, signedness is a property of data types representing numbers in computer programs. A numeric variable is signed if it can represent both positive and negative numbers, and unsigned if it can only represent non-negative numbers .As signed numbers can represent negative numbers, they...
integer types, and a
decimal
type for decimal floating-point calculations.Java lacks the unsigned types. In particular, Java lacks a primitive type for an unsigned byte
Byte
The byte is a unit of digital information in computing and telecommunications that most commonly consists of eight bits. Historically, a byte was the number of bits used to encode a single character of text in a computer and for this reason it is the basic addressable element in many computer...
. The Java
byte
type is signed, while the C# byte
is unsigned and sbyte
is signed.Both languages feature a native
char
(character) datatype as a simple type. Although the Java char
type can be used with bitwise operators, this is actually accomplished by promoting the char
to an integer before the operation.C# has a type for high-precision (28 decimal digits) decimal arithmetic for e.g. financial and monetary applications. While Java lacks such a built-in type, the Java library does feature an arbitrary precision decimal type. This is not considered a language type and it does not support the usual arithmetic operators; rather it is a reference type which must be manipulated using the type methods. See more about arbitrary size/precision numbers below.
The C# primitive/simple types implement a number of interfaces and consequently offer a number of methods directly on instances of the types - even on the literals. The C# type names are also merely aliases for Common Language Runtime
Common Language Runtime
The Common Language Runtime is the virtual machine component of Microsoft's .NET framework and is responsible for managing the execution of .NET programs. In a process known as just-in-time compilation, the CLR compiles the intermediate language code known as CIL into the machine instructions...
types. The C#
Int64
type is exactly the same type as the long
type; the only difference is that the former is the canonical .NET name while the latter is a C# alias for it.Java does not offer methods directly on the primitive types. Instead methods which operate on the primitive values are offered through companion wrapper classes
Primitive wrapper class
A primitive wrapper class in the Java programming language is one of eight classes provided in the package to provide object methods for the eight primitive types. All of the primitive wrapper classes in Java are immutable...
. A fixed set of such wrapper classes exist each of which wraps one of the fixed set of primitive types. As an example, the Java
Long
type is a reference typeReference type
In programming language theory, a reference type is a data type that can only be accessed by references. Unlike objects of value types, objects of reference types cannot be directly embedded into composite objects and are always dynamically allocated...
which wraps the primitive
long
type. They are not the same type, however.The following table summarizes the corresponding simple/primitive types of the languages:
C# alias | .NET CLR type | Width (bits) | Range (approximate) | Java type | Java wrapper |
---|---|---|---|---|---|
8 | -128 to 127 | ||||
8 | 0 to 255 | ||||
16 | -32768 to 32767 | ||||
16 | 0 to 65535 | ||||
32 | -2,147,483,648 to 2,147,483,647 | ||||
32 | 0 to 4,294,967,295 | ||||
64 | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | ||||
64 | 0 to 18,446,744,073,709,551,615 | ||||
32 | -3.402823e38 to 3.402823e38 | ||||
64 | -1.79769313486232e308 to 1.79769313486232e308 | ||||
128 | ±1.0 × 10e−28 to ±7.9 × 10e28 | ||||
16 | \u0000 to \uFFFF | ||||
8 | false, true | ||||
Advanced numeric types
Both languages offer library-defined arbitrary size integerArbitrary-precision arithmetic
In computer science, arbitrary-precision arithmetic indicates that calculations are performed on numbers whose digits of precision are limited only by the available memory of the host system. This contrasts with the faster fixed-precision arithmetic found in most ALU hardware, which typically...
types.
Only Java offers a data type for arbitrary precision decimal point
Arbitrary-precision arithmetic
In computer science, arbitrary-precision arithmetic indicates that calculations are performed on numbers whose digits of precision are limited only by the available memory of the host system. This contrasts with the faster fixed-precision arithmetic found in most ALU hardware, which typically...
calculations and only C# offers a type for working with complex numbers.
In both languages the number of operations which can be performed are limited compared to the built-in IEEE 754 floating point types. For instance, none of the types support square root
Square root
In mathematics, a square root of a number x is a number r such that r2 = x, or, in other words, a number r whose square is x...
or logarithms.
By using the C# support for type integration through custom operator overloading
Operator overloading
In object oriented computer programming, operator overloading—less commonly known as operator ad-hoc polymorphism—is a specific case of polymorphism, where different operators have different implementations depending on their arguments...
and custom (implicit and explicit) type conversions, C# achieves better parity with the built-in types.
Java | | C# |
---|---|
Built-in compound data types
Both languages treat stringString (computer science)
In formal languages, which are used in mathematical logic and theoretical computer science, a string is a finite sequence of symbols that are chosen from a set or alphabet....
s as (immutable
Immutable object
In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created. This is in contrast to a mutable object, which can be modified after it is created...
) objects of reference type. In both languages the type contains a number of methods to manipulate strings, parse, format etc. In both languages regular expression
Regular expression
In computing, a regular expression provides a concise and flexible means for "matching" strings of text, such as particular characters, words, or patterns of characters. Abbreviations for "regular expression" include "regex" and "regexp"...
s are considered an external feature and is implemented in separate classes.
Both languages' libraries define classes for working with dates and calendars in different cultures. The Java
java.util.Date
is a mutable reference type where the C# System.DateTime
is a struct value type. C# additionally define a TimeSpan
type for working with time periods. Both languages support date/time arithmetic according to different cultures.Reference types
Both languages use classes and interfaces as the primary means for defining new, object-oriented types. See below for further details.Value types
C# allows the programmer to create user-defined value typeValue type
In computer science, the term value type is commonly used to refer to one of two kinds of data types: Types of values or Types of objects with deep copy semantics.- Types of Values :...
s, using the
struct
keyword. Unlike classes, and like the standard primitives, such value types are passed and assigned by value rather than by reference. They can also be part of an object (either as a field or boxed), or stored in an array, without the memory indirection that normally exists for class types.Because value types have no notion of a null value and can be used in arrays without initialization, they always come with an implicit default constructor that essentially fills the struct memory space with zeroes. The programmer can only define additional constructors with one or more arguments. Value types do not have virtual method table
Virtual method table
A virtual method table, virtual function table, dispatch table, or vtable, is a mechanism used in a programming language to support dynamic dispatch ....
s, and because of that (and the fixed memory footprint), they are implicitly sealed. However, value types can (and frequently do) implement interfaces. For example, the built-in integer types implement a number of interfaces.
Apart from the built-in primitive types, Java does not include the concept of value types.
Enumerations
Java | C# | |
---|---|---|
Definition | In Java, both the enumeration type and (optionally) the individual enumeration values are Java classes. The only valid values are the ones listed in the enumeration. The enumeration type may declare or override members (such as a dedicated toString method) which will be inherited by the individual enumerated values. The individual enumerated values may in turn override members or even define new members only valid for that specific value. |
Enumeration Enumeration In mathematics and theoretical computer science, the broadest and most abstract definition of an enumeration of a set is an exact listing of all of its elements . The restrictions imposed on the type of list used depend on the branch of mathematics and the context in which one is working... s in C# are implicitly derived from the Enum type which again is a value type derivative. The value set of a C# enumeration is defined by the underlying type which can be a signed or unsigned integer type of 8, 16, 32 or 64 bits. The enumeration definition defines names for the selected integer values. By default the first name is assigned the value 0 (zero) and the following names are assigned in increments of 1. Any value of the underlying primitive type is a valid value of the enumeration type, though an explicit cast may be needed to assign it. |
Combining | Java enumeration set and map collections provide functionality to combine multiple enumeration values to a combined value. These special collections allows compiler optimization to minimize the overhead incurred by using collections as the combination mechanism. | C# supports bit-mapped enumerations where an actual value may be a combination of enumerated values bitwise or'ed together. The formatting and parsing methods implicitly defined by the type will attempt to use these values. |
In both C# and Java, programmers can use enumerations in a switch statement
Switch statement
In computer programming, a switch, case, select or inspect statement is a type of selection control mechanism that exists in most imperative programming languages such as Pascal, Ada, C/C++, C#, Java, and so on. It is also included in several other types of languages...
without conversion to a string or primitive integer type.
Delegates / method references
C# implements object oriented method pointers in the form of delegatesDelegate (.NET)
A delegate is a form of type-safe function pointer used by the .NET Framework. Delegates specify a method to call and optionally an object to call the method on. They are used, among other things, to implement callbacks and event listeners....
. A delegate is a special type which can capture a type-safe reference to a method. This reference can then be stored in a delegate-type variable or passed to a method through a delegate parameter for later invocation. C# delegates support covariance and contravariance
Covariance and contravariance (computer science)
Within the type system of a programming language, covariance and contravariance refers to the ordering of types from narrower to wider and their interchangeability or equivalence in certain situations ....
, and can hold a reference to any signature-compatible static method, instance method, anonymous method or lambda expression
Lambda expression
Lambda expression may refer to:*Anonymous function*Lambda calculus#Definition...
.
Delegates should not be confused with closures and inline functions. The concepts are related because a reference to a closure/inline function must be captured in a delegate reference to be useful at all. But a delegate does not always reference an inline function, it can also reference existing static or instance methods. Delegates form the basis of C# events but should not be confused with those either.
Delegates were deliberately left out of Java because they were considered unnecessary and detrimental to the language, and because of potential performance issues. Instead, an alternative mechanism must be used. The wrapper pattern, which resembles the delegates of C# in that it barely allows the client to access one or more client-defined subroutines through a known interface, is one way to design such a mechanism.
Java | | C# |
---|---|
Lifted (nullable) types
C# allows value/primitive/simple types to be "lifted" to allow the specialnull
value in addition to the type's native values. A type is lifted by adding a ?
suffix to the type name. Conversions are implicitly defined to convert between values of the base and the lifted type. The lifted type can be compared against null
or it can be tested for HasValue
. Also, lifted operators are implicitly and automatically defined based on their non-lifted base, where — with the exception of some boolean operators — a null argument will propagate to the result.Java does not support type lifting as a concept, but all of the built-in primitive types have corresponding wrapper types, which do support the
null
value by virtue of being reference types (classes).According to the Java spec, any attempt to dereference the null reference must result in an exception being thrown at run-time, specifically a NullPointerException. (It would not make sense to dereference it otherwise, because, by definition, it points to no object in memory.) This also applies when attempting to unbox a variable of a wrapper type, which evaluates to null: the program will throw an exception, because actually there is no object to be unboxed - and therefore no boxed value to take part in the subsequent computation.
The following example illustrates the different behavior. In C#, the lifted * operator propagates the
null
value of the operand; in Java, unboxing the null reference throws an exception.Java | | C# |
---|---|
Not all C# lifted operators have been defined to propagate
null
unconditionally if one of the operands is null
. Specifically, the boolean operators have been lifted to support ternary logicTernary logic
In logic, a three-valued logic is any of several many-valued logic systems in which there are three truth values indicating true, false and some indeterminate third value...
thus keeping impedance with SQL
SQL
SQL is a programming language designed for managing data in relational database management systems ....
.
The Java boolean operators do not support ternary logic, nor is it implemented in the base class library.
Late-bound (dynamic) type
C# features a late boundName binding
In programming languages, name binding is the association of objects with identifiers. An identifier bound to an object is said to reference that object. Machine languages have no built-in notion of identifiers, but name-object bindings as a service and notation for the programmer is implemented...
dynamic type which supports no-reflection dynamic invocation, interoperability with dynamic languages as well as ad-hoc binding to (for example) document object models. The
dynamic
type resolves member access dynamically at runtime as opposed to statically/virtual at compile time. The member lookup mechanism is extensible with traditional reflection as a fall-back mechanism.There are several use cases for the
dynamic
type in C#:
- Less verbose use of reflection: By casting an instance to the
dynamic
type, members such as properties, methods, events etc. can be directly invoked on the instance without using the reflection API directly. - Interoperability with dynamic languages: The dynamic type comes with a hub-and-spoke support for implementing dynamically typed objects and common runtime infrastructure for efficient member lookup.
- Creating dynamic abstractions on the fly: For instance, a dynamic object could provide simpler access to document object models such as XMLXMLExtensible Markup Language is a set of rules for encoding documents in machine-readable form. It is defined in the XML 1.0 Specification produced by the W3C, and several other related specifications, all gratis open standards....
or XHTMLXHTMLXHTML is a family of XML markup languages that mirror or extend versions of the widely-used Hypertext Markup Language , the language in which web pages are written....
documents.
Java does not support a late-bound type. The use cases for C# dynamic type have different corresponding constructs in Java:
- For dynamic late-bound by-name invocation of preexisting types, reflection should be used.
- For interoperability with dynamic languages, some form of interoperability API specific to that language will have to be used. The Java Virtual Machine platform does have multiple dynamic languages implemented on top of it, but there is no common standard for how to pass objects between languages. Usually this will involve some form of reflection or reflection-like API. As an example of how to use JavaFX objects from Java, see How to Use JavaFX in Your Swing Application.
- For creating and interacting with objects entirely at runtime, e.g. interaction with a document object model abstraction, a specific abstraction API will have to be used.
Dynamic language interoperability
The C#
dynamic
enables seamless interoperability with dynamic (late-bound) languages by allowing C# code to manipulate foreign objects using the same syntax as if they were native C# objects. Lacking this capability, Java developers must use a Java based API to access such objects. Consider a Ruby class (defined in a file called Deepthought.rb) which has 2 attributes (a,b) with read/write accessors and a Calculate
method which returns the product of the attributes. The following examples illustrate how to instantiate and use such a class from within Java and C#, respectively.Java | C# | ||
---|---|---|---|
initialization | |||
usage | |||
notes |
|
dynamic objects are themselves of dynamic type. When type inference (the var keyword) is used, the variables calc and answer are inferred dynamic/late-bound.new is a reserved word. The @ prefix allows keywords to be used as identifiers. |
Pointers
C# allows use of pointers and corresponding pointer arithmetic. Pointers and pointer-arithmetic are potentially unsafe in a managed environment as they can be used to bypass the strict rules for object access. C# addresses that concern by requiring that code blocks or methods that use the feature be marked with theunsafe
keyword, so that all clients of such code can be aware that the code may be less secure than otherwise. The compiler requires the /unsafe switch to allow compilation of a program that uses such code, and assemblies containing unsafe code may only execute if explicitly granted security permissions. Generally, unsafe code is either used to allow better interoperabilityInteroperability
Interoperability is a property referring to the ability of diverse systems and organizations to work together . The term is often used in a technical systems engineering sense, or alternatively in a broad sense, taking into account social, political, and organizational factors that impact system to...
with unmanaged APIs or system calls (which are inherently "unsafe"), or for performance reasons.
Java does not permit pointers or pointer-arithmetic within the Java runtime environment and native interop is handled externally through JNI or other mechanisms.
Object handling
Both C# and Java are designed from the ground up as object oriented languages using dynamic dispatchDynamic dispatch
In computer science, dynamic dispatch is the process of mapping a message to a specific sequence of code at runtime. This is done to support the cases where the appropriate method can't be determined at compile-time...
, with syntax similar to C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
(C++ in turn derives from C
C (programming language)
C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system....
). Neither language is a superset of C or C++, however.
Both languages mainly use garbage collection
Garbage collection (computer science)
In computer science, garbage collection is a form of automatic memory management. The garbage collector, or just collector, attempts to reclaim garbage, or memory occupied by objects that are no longer in use by the program...
as a means of reclaiming memory resources, rather than explicit deallocation of memory. In both cases, if an object holds resources of different kinds other than memory, such as file handles, graphical resources, etc., then it will have to be notified explicitly when the application no longer uses it. Both C# and Java offer interfaces for such deterministic disposal and both C# and Java (since Java 7) feature automatic resource management statements which will automatically invoke the disposal/close methods on those interfaces.
Both languages include thread synchronization
Synchronization
Synchronization is timekeeping which requires the coordination of events to operate a system in unison. The familiar conductor of an orchestra serves to keep the orchestra in time....
mechanisms as part of their language syntax.
Object initialization
In both C# and Java, an object's fields can be initialized either by variable initializers (expressions that can be assigned to variables where they are defined) or by constructors (special subroutines that are executed when an object is being created). In addition, Java contains instance initializers, which are anonymous blocks of code with no arguments that are run after the explicit (or implicit) call to a superclass's constructor but before the constructor is executed.C# initializes object fields in the following order when creating an object:
- Derived static fields
- Derived static constructor
- Derived instance fields
- Base static fields
- Base static constructor
- Base instance fields
- Base instance constructor
- Derived instance constructor
Some of the above fields may not be applicable (e.g. if an object does not have static fields). Derived fields are those that are defined in the object's direct class, while base field is a term for the fields that are defined in one of the object's superclasses. Note that an object representation in memory contains all fields defined in its class or any of its superclasses, even if some fields in superclasses are defined as private.
It is guaranteed that any field initializers take effect before any constructors are called, since both the instance constructor of the object's class and its superclasses are called after field initializers are called. There is, however, a potential trap in object initialization when a virtual method is called from a base constructor. The overridden method in a subclass may reference a field that is defined in the subclass, but this field may not have been initialized because the constructor of the subclass that contains field initialization is called after the constructor of its base class.
In Java, the order of initialization is as follows:
- Invocation of another constructor (either of the object's class or of the object's superclass)
- Instance variable initializers and instance initializers (in the order they appear in the source code)
- The constructor body
Like in C#, a new object is created by calling a specific constructor. Within a constructor, the first statement may be an invocation of another constructor. If this is omitted, the call to the argumentless constructor of the superclass is added implicitly by the compiler. Otherwise, either another overloaded constructor of the object's class can be called explicitly, or a superclass constructor can be called. In the former case, the called constructor will again call another constructor (either of the object's class or its subclass) and the chain sooner or later ends up at the call to one of the constructors of the superclass.
After another constructor is called (which causes direct invocation of the superclass constructor, and so forth, down to the Object class), instance variables defined in the object's class are initialized. Even if there are no variable initializers explicitly defined for some variables, these variables are initialized to default values. Note that instance variables defined in superclasses are already initialized by this point, because they were initialized by a superclass constructor when it was called (either by the constructor's code or by variable initializers performed before the constructor's code or implicitly to default values). In Java, variable initializers are executed according to their textual order in the source file.
Finally, the constructor body is executed. This ensures proper order of initialization, i.e. the fields of a base class finish initialization before initialization of the fields of an object class begins.
There are two main potential traps in Java's object initialization. First, variable initializers are expressions that can contain method calls. Since methods can reference any variable defined in the class, the method called in a variable initializer can reference a variable that is defined below the variable being initialized. Since initialization order corresponds to textual order of variable definitions, such a variable would not be initialized to the value prescribed by its initializer and would contain the default value.
Another potential trap is when a method that is overridden in the derived class is called in the base class constructor, which can lead to behavior the programmer would not expect when an object of the derived class is created. According to the initialization order, the body of the base class constructor is executed before variable initializers are evaluated and before the body of the derived class constructor is executed. The overridden method called from the base class constructor can, however, reference variables defined in the derived class, but these are not yet initialized to the values specified by their initializers or set in the derived class constructor. The latter issue applies to C# as well, but in a less critical form since in C# methods are not overridable by default.
Arrays and collections
Arrays and collectionsCollection (computing)
In computer science, a collection is a grouping of some variable number of data items that have some shared significance to the problem being solved and need to be operated upon together in some controlled fashion. Generally, the data items will be of the same type or, in languages supporting...
are concepts featured by both languages. The syntax used to declare and access arrays is identical, except that C# has added syntax for declaring and manipulating multidimensional arrays.
Java | | C# |
---|---|
Arrays are implicitly direct specializations of Object . They are not unified with collection types. |
Arrays in C# are implicitly specializations the System.Array class which implements a number of collection interfaces. |
Arrays and collections are completely separate with no unification. Arrays cannot be passed where sequences or collections are expected | Arrays can be passed where sequences (IEnumerable s) or collections/list interfaces are expected. However, the collection operations which alter the number of elements (insert/add/remove) will throw exceptions as these operations are not supported by arrays. |
The for statement accepts either arrays or Iterable s. All collections implement Iterable . This means that the same short syntax can be used in for-loops. |
The foreach statement iterates through a sequence using the IEnumerable orIEnumerable<T> interface. Because arrays always implicitly implement these interfaces, the loop will iterate through arrays as well. |
In both languages arrays are covariant. This means that a String[] array is assignable to variables of Object[] because String is a specialization of (assignable to) Object . In both languages the arrays will perform a type check when inserting new values because type-safety would otherwise be compromised. This is in contrast to how generic collections have been implemented in both languages. |
|
Multidimensional arrays only in the form of arrays of arrays (also known as "jagged" arrays); Java does not have true rectangular multidimensional arrays. | True multidimensional "rectangular" arrays, as well as arrays of arrays (jagged arrays). |
Multidimensional arrays can in some cases increase performance because of increased locality (as there is a single pointer dereference, instead of one for every dimension of the array as is the case for jagged arrays). However, since all array element access in a multidimensional array requires multiplication/shift between the two or more dimensions, this is an advantage only in very random access scenarios.
Another potential advantage is that the entire multidimensional array can be allocated with a single application of operator
new
, while jagged arrays require loops and allocations for every dimension. Note, though, that Java provides a syntactic construct for allocating a multidimensional jagged array with regular lengths; the loops and multiple allocations are then performed by the virtual machine and need not be explicit at the source level.Both languages feature an extensive set of collection types which includes various ordered and unordered types of lists, maps/dictionaries, sets, etc.
Operator overloading and implicit and explicit conversions
Operator overloadingOperator overloading
In object oriented computer programming, operator overloading—less commonly known as operator ad-hoc polymorphism—is a specific case of polymorphism, where different operators have different implementations depending on their arguments...
and user-defined casts
Type conversion
In computer science, type conversion, typecasting, and coercion are different ways of, implicitly or explicitly, changing an entity of one data type into another. This is done to take advantage of certain features of type hierarchies or type representations...
are separate features which both aim to allow new types to become first-class citizens in the type system. By using these features in C#, types such as
Complex
and decimal
have been integrated so that the usual operators like addition and multiplication work with the new types.Java does not include operator overloading nor custom conversions in order to prevent abuse of the feature, and to keep the language simple.
Indexers
C# also includes indexers which can be considered a special case of operator overloading (like the C++operator[]
), or parameterized get
/set
properties. An indexer is a property named this[]
which uses one or more parameters (indexes); the indices can be objects of any type:Java does not include indexers. The common Java pattern involves writing explicit getters and setters where a C# programmer would use an indexer.
Partial classes
C# allows a class definition to be split across several source files using a feature called partial classes. Each part must be marked with the keywordpartial
. All the parts must be presented to the compiler as part of a single compilation. Parts can reference members from other parts. Parts can implement interfaces and one part can define a base class. The feature is useful in code generation scenarios (such as UIUser interface
The user interface, in the industrial design field of human–machine interaction, is the space where interaction between humans and machines occurs. The goal of interaction between a human and a machine at the user interface is effective operation and control of the machine, and feedback from the...
design) where a code generator can supply one part and the developer another part to be compiled together. The developer can thus edit their part without the risk of a code generator overwriting that code at some later time. Unlike the class extension mechanism, a partial class allows "circular" dependencies among its parts as they are guaranteed to be resolved at compile time. Java has no corresponding concept.
Inner and local classes
Both languages allow inner classes, where a class is defined lexically inside another class. However, in each language these inner classes have rather different semantics.In Java, unless the inner class is declared
static
, a reference to an instance of an inner class carries a reference to the outer class with it. As a result, code in the inner class has access to both the static and non-static members of the outer class. To create an instance of a non-static inner class, one has to name the instance of the embracing outer class. This is done via a new new
-operator introduced in JDK 1.3: outerClassInstance.new Outer.InnerClass
. This can be done in any class that has a reference to an instance of the outer class.In C#, an inner class is conceptually the same as a normal class. In a sense, the outer class only acts as a namespace. Thus, code in the inner class cannot access non-static members of the outer class unless it does so through an explicit reference to an instance of the outer class. Programmers can declare the inner class private to allow only the outer class to have any access to it.
Java provides another feature called local classes or anonymous classes, which can be defined within a method body. These are generally used to implement an interface with only one or two methods, which are typically event handlers. However, they can also be used to override virtual methods of a superclass. The methods in those local classes have access to the outer method's local variables declared
final
. C# satisfies the use-cases for these by providing anonymous delegatesDelegate (.NET)
A delegate is a form of type-safe function pointer used by the .NET Framework. Delegates specify a method to call and optionally an object to call the method on. They are used, among other things, to implement callbacks and event listeners....
; see event handling for more about this.
C# also provides a feature called anonymous types/classes, but it is rather different from Java's concept with the same name. It allows the programmer to instantiate a class by providing only a set of names for the properties the class should have, and an expression to initialize each. The types of the properties are inferred from the types of those expressions. These implicitly-declared classes are derived directly from object.
Explicit member implementation
C# also has "Explicit Member Implementation" which allows a class to specifically implement methods of an interfaceInterface (computer science)
In the field of computer science, an interface is a tool and concept that refers to a point of interaction between components, and is applicable at the level of both hardware and software...
, separate to its own class methods, or to provide different implementations for two methods with the same name and signature inherited from two base interfaces.
Events
C# multicast-delegates are called events. Events provide support for event-driven programmingEvent-driven programming
In computer programming, event-driven programming or event-based programming is a programming paradigm in which the flow of the program is determined by events—i.e., sensor outputs or user actions or messages from other programs or threads.Event-driven programming can also be defined as an...
and is an implementation of the observer pattern
Observer pattern
The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods...
. To support this there is a specific syntax to define events in classes, and operators to register, unregister or combine event handlers.
See here for information about how events are implemented in Java.
Boxing and unboxing
Both languages allow automatic boxing and unboxing, i.e. they allow for implicit casting between any primitive types and the corresponding reference types.In C#, the primitive types are subtypes of the Object type. In Java this is not true; any given primitive type and the corresponding wrapper type have no specific relationship with each other, except for autoboxing and unboxing, which act as syntactic sugar
Syntactic sugar
Syntactic sugar is a computer science term that refers to syntax within a programming language that is designed to make things easier to read or to express....
for interchanging between them. This was done intentionally, to maintain backward compatibility with prior versions of Java, in which no automatic casting was allowed, and the programmer worked with two separate sets of types: the primitive types, and the wrapper (reference) type hierarchy.
This difference has the following consequences. First of all, in C#, primitive types can define methods, such as an override of Object's
ToString
method. In Java, this is task is accomplished by the primitive wrapper classPrimitive wrapper class
A primitive wrapper class in the Java programming language is one of eight classes provided in the package to provide object methods for the eight primitive types. All of the primitive wrapper classes in Java are immutable...
es.
Secondly, in Java an extra cast is needed whenever one tries to directly dereference
Reference (computer science)
In computer science, a reference is a value that enables a program to indirectly access a particular data item, such as a variable or a record, in the computer's memory or in some other storage device. The reference is said to refer to the data item, and accessing those data is called...
a primitive value, as it will not be boxed automatically. The expression
((Integer)42).toString
will convert an integer literal to string in Java while 42.ToString
performs the same operation in C#. This is because the latter one is actually an instance call on the primitive value 42
, while the former one is an instance call on an object of type java.lang.Integer.Finally, another difference is that Java makes heavy use of boxed types in generics
Generic programming
In a broad definition, generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters...
(see below).
Generics
In the field of genericsGeneric programming
In a broad definition, generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters...
the two languages show a superficial syntactical similarity, but they have deep underlying differences.
Type erasure versus reified generics
Generics in JavaGenerics in Java
Generics are a facility of generic programming that was added to the Java programming language in 2004 as part of J2SE 5.0. They allow "a type or method to operate on objects of various types while providing compile-time type safety." A common use of this feature is when using a Java Collection...
are a language-only construction; they are implemented only in the compiler. The generated classfiles include generic signatures only in the form of metadata (allowing the compiler to compile new classes against them). The runtime has no knowledge of the generic type system; generics are not part of the JVM. Instead, generics classes and methods are transformed during compilation through a process known as type erasure
Type erasure
In programming languages, type erasure refers to the compile-time process by which explicit type annotations are removed from a program, before it is executed at run-time. An operational semantics that does not require programs to be accompanied by types is called a type-erasure semantics, to be...
. During this process the compiler replaces all generic types with their raw version and inserts casts/checks appropriately in client code where the type and its methods are used. The resulting byte code will contain no references to any generic types or parameters (See also Generics in Java
Generics in Java
Generics are a facility of generic programming that was added to the Java programming language in 2004 as part of J2SE 5.0. They allow "a type or method to operate on objects of various types while providing compile-time type safety." A common use of this feature is when using a Java Collection...
).
The language specification intentionally prohibits certain uses of generics; this is necessary to allow for implementing generics through type erasure
Type erasure
In programming languages, type erasure refers to the compile-time process by which explicit type annotations are removed from a program, before it is executed at run-time. An operational semantics that does not require programs to be accompanied by types is called a type-erasure semantics, to be...
, and to allow for migration compatibility.
C# builds on support for generics from the virtual execution system itself, i.e. it is not just a language feature. The language is merely a front-end for cross-language generics support in the CLR
Common Language Runtime
The Common Language Runtime is the virtual machine component of Microsoft's .NET framework and is responsible for managing the execution of .NET programs. In a process known as just-in-time compilation, the CLR compiles the intermediate language code known as CIL into the machine instructions...
. During compilation generics are verified for correctness, but code generation for actually implementing the generics are deferred to class-load time. Client code (code invoking generic methods/properties) are fully compiled and can safely assume generics to be type-safe. This is called reification
Reification (computer science)
Reification is the process by which an abstract idea about a computer program is turned into an explicit data model or other object created in a programming language. A computable/addressable object — a resource — is created in a system as a proxy for a non computable/addressable object...
. At runtime, when a unique set of type parameters for a generic class/method/delegate is encountered for the first time, the class loader/verifier will synthesize a concrete class descriptor and generate method implementations. During the generation of method implementations all reference types will be considered a single type, as reference types can safely share the same implementations. Note, this is merely for the purpose of the implementing code. Different sets of reference types will still have unique type descriptors; their method tables will merely point to the same code.
The following list illustrates some differences between Java and C# when managing generics. It is not exhaustive:
Java | |C# |
---|---|
Type checks and downcasts are injected into client code (the code referencing the generics). Compared to non-generic code with manual casts, these casts will be the same. But compared to compile-time verified code which would not need runtime casts and checks, these operations represent a performance overhead. | C#/.NET generics guarantees type-safety and is verified at compile time and no extra checks/casts are necessary at runtime. Hence, generic code will run faster than non-generic code (and type-erased code) which require casts when handling non-generic or type-erased objects. |
Cannot use primitive types as type parameters; instead the developer must use the wrapper type corresponding to the primitive type. This incurs extra performance overhead by requiring boxing and unboxing conversions as well a memory and garbage collection pressure because the wrappers will be heap allocated as opposed to stack allocated. | Primitive and value types are allowed as type parameters in generic realizations. At runtime code will be synthesized and compiled for each unique combination of type parameters upon first use. Generics which are realized with primitive/value type do not require boxing/unboxing conversions. |
Generic exceptions are not allowed and a type parameter cannot be used in a catch clause | Can both define generic exceptions and use those in catch clauses |
Static members are shared across all generic realizations (during type erasure all realizations are folded into a single class) | Static members are separate for each generic realization. A generic realization is a unique class. |
Type parameters cannot be used in declarations of static fields/methods or in definitions of static inner classes | No restrictions on use of type parameters |
Cannot create an array where the component type is a generic realization (concrete parameterized type) |
A generic realization is a 1st class citizen and can be used as any other class; also an array component |
Cannot create an array where the component type is a type parameter |
Type parameters represent actual, discrete classes and can be used like any other type within the generic definition. |
There is no class literal for a concrete realization of a generic type | A generic realization is an actual class. |
instanceof is not allowed with type parameters or concrete generic realizations |
The is and as operators work the same for type parameters as for any other type. |
Cannot create new instances using a type parameter as the type | With a constructor constraint, generic methods or methods of generic classes can create instances of classes which have default constructors. |
Type information is erased during compilation. Special extensions to reflection must be used to discover the original type. | Type information about C# generic types is fully preserved at runtime, and allows complete reflection support as well as instantiation of generic types. |
Reflection cannot be used to construct new generic realizations. During compilation extra code (typecasts) are injected into the client code of generics. This precludes creating new realizations later. | Reflection can be used to create new realizations for new combinations of type parameters. |
C# allows generics directly for primitive types. Java, instead, allows the use of boxed types as type parameters (e.g.,
List<Integer>
instead of List<int>
). This comes at a cost since all such values need to be boxed/unboxed when used, and they all need to be heap-allocated. However, a generic type can be specialized with an array type of a primitive type in Java, for example List<int[]>
is allowed.Migration compatibility
Java's type erasure design was motivated by a design requirement to achieve migration compatibility - not to be confused with backward compatibilityBackward compatibility
In the context of telecommunications and computing, a device or technology is said to be backward or downward compatible if it can work with input generated by an older device...
. In particular, the original requirement was "... there should be a clean, demonstrable migration path for the Collections APIs that were introduced in the Java 2 platform". This was designed so that any new generic collections should be passable to methods which expected one of the pre-existing collection classes.
C# generics were introduced into the language while preserving full backward compatibility, but did not preserve full migration compatibility: Old code (pre C# 2.0) runs unchanged on the new generics-aware runtime without recompilation. As for migration compatibility, new generic collection classes and interfaces were developed which supplemented the non-generic .NET 1.x collections rather than replacing them. In addition to generic collection interfaces, the new generic collection classes implement the non-generic collection interfaces where possible. This prevents the use of new generic collections with pre-existing (non-generic aware) methods, if those methods are coded to use the collection classes.
Covariance and contravariance
Covariance and contravariance is supported by both languages. Java has use-site variance which allows a single generic class to declare members using both co- and contravariance. C# has define-site variance for generic interfaces and delegates. Variance is not supported directly on classes but is supported through their implementation of variant interfaces. C# also has use-site covariance support for methods and delegates.Special feature keywords
keyword | feature, example usage |
---|---|
checked , unchecked |
In C#, checked statement blocks or expressions can enable run-time checking for arithmetic overflowArithmetic overflow The term arithmetic overflow or simply overflow has the following meanings.# In a computer, the condition that occurs when a calculation produces a result that is greater in magnitude than that which a given register or storage location can store or represent.# In a computer, the amount by which a... . |
get , set |
C# implements properties as part of the language syntax with their optional corresponding get and set accessors, as an alternative for the accessor methods used in Java, which is not a language feature but a coding-pattern based on method name conventions. |
goto |
C# supports the goto keyword. This can occasionally be useful, for example for implementing finite state machineFinite state machine A finite-state machine or finite-state automaton , or simply a state machine, is a mathematical model used to design computer programs and digital logic circuits. It is conceived as an abstract machine that can be in one of a finite number of states... s or for generated code, but the use of a more structured method of control flow Control flow In computer science, control flow refers to the order in which the individual statements, instructions, or function calls of an imperative or a declarative program are executed or evaluated.... is usually recommended (see criticism of the goto statement). Java does not support the goto statement (but goto is a reserved word). However, Java does support labeled break and continue statements, which in certain situations can be used when a goto statement might otherwise be used. |
lock |
In C#, the lock keyword is a shorthand for synchronizing access to a block of code across threads (using a Monitor ), wrapped in a try ... finally block. |
out , ref |
C# has support for output and reference parameters Parameter (computer science) In computer programming, a parameter is a special kind of variable, used in a subroutine to refer to one of the pieces of data provided as input to the subroutine. These pieces of data are called arguments... . These allow returning multiple output values from a method, or passing values by reference. |
strictfp |
Java uses strictfp to guarantee the results of floating point operations remain the same across platforms. |
switch |
In C#, the switch statement Switch statement In computer programming, a switch, case, select or inspect statement is a type of selection control mechanism that exists in most imperative programming languages such as Pascal, Ada, C/C++, C#, Java, and so on. It is also included in several other types of languages... also operates on strings and longs but only allows fallthrough for empty statements. Java's switch statement does not operate on strings (before Java 7) nor long primitive type but falls through for all statements (excluding those with 'break '). |
throws |
Java requires every method to declare the checked exceptions or superclasses of the checked exceptions that it can throw. Any method can also optionally declare the unchecked exception that it throws. C# has no such syntax. |
using |
In C#, using causes the Dispose method (implemented via the IDisposable interface) of the object declared to be executed after the code block has run or when an exception is thrown within the code block. |
Numeric applications
To adequately support applications in the field of mathematical and financial computation, several language features exist. In this category, Java provides the strictfpStrictfp
strictfp is a keyword in the Java programming language that restricts floating-point calculations to ensure portability. It was introduced into Java with the Java virtual machine version 1.2.-Basis:...
keyword, which enables strict floating-point calculations for a region of code. This will ensure that calculations return exactly the same result on all platforms. C# provides no equivalent, but does provide the built-in
decimal
type, for accurate decimal floating-point calculations. This forgoes the problems that exist with binary floating-point representations (float
, double
). Such binary representations are not suited to accurately represent decimal numbers and hence introduce rounding errors. For financial applications, an accurate decimal type is essential.The class also provides such characteristics for Java.
BigDecimal
and are types provided with Java that allow arbitrary-precision representation of numbers. the current stable release of the .NET framework (4.0) includes classes for manipulating arbitrary-precision integers and complex numbers (with operators overloaded for easy use so that BigInteger objects can be used just like any other primitive data type), but still the .NET Framework lacks classes to deal with arbitrary-precision floating point numbers (see software for arbitrary-precision arithmetic).In Java there is no way to provide the same level of integration for library-defined types such as
BigDecimal
or complex numberComplex number
A complex number is a number consisting of a real part and an imaginary part. Complex numbers extend the idea of the one-dimensional number line to the two-dimensional complex plane by using the number line for the real part and adding a vertical axis to plot the imaginary part...
s as there is for the primitive types. For this purpose, C# provides the following:
- Operator overloadingOperator overloadingIn object oriented computer programming, operator overloading—less commonly known as operator ad-hoc polymorphism—is a specific case of polymorphism, where different operators have different implementations depending on their arguments...
and indexers providing convenient syntax (see below). - Implicit and explicit conversions; allow conversions such as exist for the built-in
int
type that can implicitly convert tolong
. - Valuetypes and generics based on valuetypes; in Java every custom type must be allocated on the heap, which is detrimental for performance of both custom types and collections.
In addition to this, C# can help mathematical applications with the
checked
and unchecked
operators that allow the enabling or disabling of run-time checking for arithmetic overflowArithmetic overflow
The term arithmetic overflow or simply overflow has the following meanings.# In a computer, the condition that occurs when a calculation produces a result that is greater in magnitude than that which a given register or storage location can store or represent.# In a computer, the amount by which a...
for a region of code.
Methods
Methods in C# are non-virtualVirtual function
In object-oriented programming, a virtual function or virtual method is a function or method whose behaviour can be overridden within an inheriting class by a function with the same signature...
by default, and have to be declared virtual explicitly if desired. In Java, all non-static non-private methods are virtual. Virtuality guarantees that the most recent override
Method overriding (programming)
Method overriding, in object oriented programming, is a language feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its superclasses or parent classes...
for the method will always be called, but incurs a certain runtime cost on invocation as these invocations cannot be normally inlined
Inline expansion
In computing, inline expansion, or inlining, is a manual or compiler optimization that replaces a function call site with the body of the callee. This optimization may improve time and space usage at runtime, at the possible cost of increasing the final size of the program In computing, inline...
, and require an indirect call via the virtual method table
Virtual method table
A virtual method table, virtual function table, dispatch table, or vtable, is a mechanism used in a programming language to support dynamic dispatch ....
. However, some JVM implementations, including the Sun reference implementation, implement inlining of the most commonly called virtual methods.
Java methods are virtual by default (although they can be "sealed" by using the
final
modifier to disallow overriding). There is no way to let derived classes define a new, unrelated method with the same name.This means that by default in Java, and only when explicitly enabled in C#, new methods may be defined in a derived class with the same name and signature as those in its base class. When the method is called on a superclass reference of such an object, the "deepest" overridden implementation of the base class' method will be called according to the specific subclass of the object being referenced.
In some cases, when a subclass introduces a method with the same name and signature as a method already present in the base class, problems can occur. In Java, this will mean that the method in the derived class will implicitly override the method in the base class, even though that may not be the intent of the designers of either class.
To mitigate this, C# requires that if a method should be overridden, the
override
keyword must be specified. Otherwise, the method will "hide" the inherited method. A compiler warning to this effect is issued, which can be silenced by specifying the new
keyword. This avoids the problem which can arise from a base class being extended with a protected/public method whose signature is already in use by a derived class.Generator methods
Any C# method declared as returningIEnumerable
, IEnumerator
and/or the generic versions of these interfaces can be implemented using yield
syntax. This is a form of limited, compiler-generated continuations and can drastically reduce the code required to traverse or generate sequences, although that code is just generated by the compiler instead. The feature can also be used to implement infinite sequences, e.g. the sequence of Fibonacci numbers.Java does not have an equivalent feature. Instead generators are typically defined by providing a specialized implementation of a well-known collection or iterable interface, which will compute each element on demand. For such a generator to be used in a for each statement, it must implement interface
java.lang.Iterable
.Below these two approaches are shown for the two languages. Both use the designated iterator/enumerator interface of the language. Note how the C# version use multiple
yield return
statements to alternate between accumulating in one or the other local variable. The Java version would have to use an extra boolean flag to achieve the same, or use a temporary variable as in this case.Java | C# |
---|---|
Explicit interface implementation
In either language if a method (or property in C#) is specified with the same name and signature in multiple interfaces, the members will clash when a class is designed which implements those interfaces. An implementation will by default implement a common method for all of the interfaces. If separate implementations are required (because the methods really do serve separate purposes, or because return values differ between the interfaces) C#'s explicit interface implementation will solve the problem, though allowing different results for the same method, depending on the current cast of the object. In Java there is no way to solve this problem other than cleaning the code and refactoring one or more of the interfaces to avoid name clashes.Closures
A closure is an inline function which captures variables from its lexical scope.C# supports closures as anonymous methods or lambda expressions with full-featured closure
Closure (computer science)
In computer science, a closure is a function together with a referencing environment for the non-local variables of that function. A closure allows a function to access variables outside its typical scope. Such a function is said to be "closed over" its free variables...
semantics.
In Java, anonymous inner classes remains the preferred way to emulate closures. Aside from being a more verbose construction, this approach also has some drawbacks compared to real closures, such as limited access to variables from the enclosing scopes (only final members can be referenced).
When a reference to a method can be passed around for later execution, a problem arises about what to do when the method has references to variables/parameters in its lexical scope. C# closures can fully capture any variable/parameter from its lexical scope. In Java's anonymous inner classes only references to final members of the lexical scope are allowed, thus requiring the developer to artificially introduce extra levels of indirections and boxing primitive types if he wants to reference and update those from the inner class.
While Java does not currently feature closures, it has been announced that some form of closures or lambdas will be included in JDK 8 which at latest update (10 October 2010) is scheduled for release "late 2012".
Language integrated query (LINQ)
C#s Language INtegrated Query (LINQ)LINQ
Linq is a word-based card game from Endless Games, introduced at the American International Toy Fair in 2005.Game play requires at least four players, two of whom are dealt cards with the same word, while the others receive blanks. The goal is to gain points by correctly naming the players with...
is not really a single feature; rather it is a number of features designed to work together to allow for in-language querying capabilities. LINQ has emerged as one of the most distinguishing features between Java and C#.
LINQ consists of the following features:
- Extension methods allow existing interfaces or classes to be extended with new methods. Implementations can be shared or an interface can have a dedicated implementation.
- Lambdas allow for expression of criteria in a functional fashion.
- Expression trees allow a specific implementation to capture a lambda as a concrete syntax tree rather than an executable block. This can be utilized by implementations to represent criteria in a different language, e.g. in the form of an SQL where clauseWhere (SQL)A WHERE clause in SQL specifies that a SQL Data Manipulation Language statement should only affect rows that meet specified criteria. The criteria are expressed in the form of predicates...
as is the case with e.g. Linq, LINQ to SQL. - Anonymous types and type inference supports capturing and working with the result type of a query. A query may both join and project over query sources which may lead to a result type which cannot be named.
- Query expressions to support a syntax familiar to SQLSQLSQL is a programming language designed for managing data in relational database management systems ....
users. - Nullable (lifted) types to allow for a better match with query providers which support nullable types, like e.g. SQLSQLSQL is a programming language designed for managing data in relational database management systems ....
.
Lambdas and expression trees
C# features a special type of in-line closureClosure (computer science)
In computer science, a closure is a function together with a referencing environment for the non-local variables of that function. A closure allows a function to access variables outside its typical scope. Such a function is said to be "closed over" its free variables...
s called lambdas. These are anonymous methods: they have a signature and a body, but no name. They are mainly used to specify local function-valued arguments in calls to other methods, a technique mainly associated with functional programming
Functional programming
In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state...
. On top of that, lambda functions can double as a way to define special data structures called expression trees. Whether they are seen as an executable function or as a data structure depends on compiler type inference and what type of variable or parameter they are assigned or cast to. Lambdas and expression trees play key roles in LINQ
LINQ
Linq is a word-based card game from Endless Games, introduced at the American International Toy Fair in 2005.Game play requires at least four players, two of whom are dealt cards with the same word, while the others receive blanks. The goal is to gain points by correctly naming the players with...
. Java does not feature lambdas or expression trees; its primary mechanism for inline scope capture and method definition is the anonymous inner class syntax.
Partial methods
Related to partial classes C# allows partial methods to be specified within partial classes. A partial method is an intentional declaration of a method with a number of restrictions on the signature. These restrictions ensure that if a definition is not actually provided by any class part, then the method and every call to it can be safely erased. This feature allows code to provide a large number of interception points (like the template methodTemplate method pattern
In software engineering, the template method pattern is a design pattern.It is a behavioral pattern, and is unrelated to C++ templates.-Introduction:A template method defines the program skeleton of an algorithm...
GoF
Design Patterns
Design Patterns: Elements of Reusable Object-Oriented Software is a software engineering book describing recurring solutions to common problems in software design. The book's authors are Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides with a foreword by Grady Booch. The authors are...
design pattern) without paying any runtime overhead if these extension points are not being used by another class part at compile time. Java has no corresponding concept.
Extension methods
Using a special this designator on the first parameter of a method, C# allows the method to act as if it were a member method of the type of the first parameter. This extension of the foreign class is purely syntactical. The extension method needs to be static and defined within a purely static class. It must obey any restriction on such external static methods and thus cannot break object encapsulation. The "extension" is only active within scopes where the namespace of the static host class has been imported. Java does not have an equivalent feature (although one is being discussed for Java 8).Conditional compilation
Unlike Java, C# implements conditional compilationConditional compilation
In computer programming, conditional compilation is compilation implementing methods which allow the compiler to produce differences in the executable produced controlled by parameters that are provided during compilation...
using preprocessor directives. It also provides a
Conditional
attributeAnnotation
An annotation is a note that is made while reading any form of text. This may be as simple as underlining or highlighting passages.Annotated bibliographies give descriptions about how each source is useful to an author in constructing a paper or argument...
to define methods that are only called when a given compilation constant is defined. This way, assertions
Assertion (computing)
In computer programming, an assertion is a predicate placed in a program to indicate that the developer thinks that the predicate is always true at that place.For example, the following code contains two assertions:...
can be provided as a framework feature with the method
Debug.Assert
, which is only evaluated when the DEBUG
constant is defined. Since version 1.4, Java provides a language feature for assertions, which are turned off at runtime by default but can be enabled using the -enableassertions
or -ea
switch when invoking the JVM.Namespaces and source files
In C#, namespaceNamespace (computer science)
A namespace is an abstract container or environment created to hold a logical grouping of unique identifiers or symbols . An identifier defined in a namespace is associated only with that namespace. The same identifier can be independently defined in multiple namespaces...
s are similar to those in C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
. Unlike package
Java package
A Java package is a mechanism for organizing Java classes into namespaces similar to the modules of Modula. Java packages can be stored in compressed files called JAR files, allowing classes to download faster as a group rather than one at a time...
names in Java, a namespace is not in any way tied to the location of the source file. While it is not strictly necessary for a Java source file location to mirror its package directory structure, it is the conventional organization.
Both languages allow importing of classes (e.g.,
import java.util.*
in Java), allowing a class to be referenced using only its name. Sometimes classes with the same name exist in multiple namespaces or packages. Such classes can be referenced by using fully qualified names, or by importing only selected classes with different names. To do this, Java allows importing a single class (e.g., import java.util.List
). C# allows importing classes under a new local name using the following syntax: using Console = System.Console
. It also allows importing specializations of classes in the form of using IntList = System.Collections.Generic.List<int>
.Java has a static import
Static import
Static import is a feature introduced in the Java programming language that allows members defined in a class as public static to be used in Java code without specifying the class in which the field is defined...
syntax that allows using the short name of some or all of the static methods/fields in a class (e.g., allowing
foo(bar)
where foo
can be statically imported from another class). C# has a static class syntax (not to be confused with static inner classes in Java), which restricts a class to only contain static methods. C# 3.0 introduces extension methodExtension method
An Extension method is a new language feature of C# starting with the 3.0 specification, as well as Visual Basic.NET starting with 9.0 and Oxygene with 2.0. Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying...
s to allow users to statically add a method to a type (e.g., allowing
foo.bar
where bar
can be an imported extension method working on the type of foo
).The Sun Microsystems
Sun Microsystems
Sun Microsystems, Inc. was a company that sold :computers, computer components, :computer software, and :information technology services. Sun was founded on February 24, 1982...
Java compiler requires that a source file name must match the only public class inside it, while C# allows multiple public classes in the same file, and puts no restrictions on the file name. C# 2.0 and later allows splitting a class definition into several files by using the
partial
keyword in the source code. In Java, a public class will always be in its own source file. In C#, source code files and logical units separation are not tightly related.Exception handling
Java supports checked exceptions (in addition to unchecked exceptions). C# only supports unchecked exceptions. Checked exceptions force the programmer to either declare the exception thrown in a method, or to catch the thrown exception using atry-catch
clause.Checked exceptions can encourage good programming practice, ensuring that all errors are dealt with. However Anders Hejlsberg
Anders Hejlsberg
Anders Hejlsberg is a prominent Danish software engineer who co-designed several popular and commercially successful programming languages and development tools...
, chief C# language architect, argues that they were to some extent an experiment in Java and that they have not been shown to be worthwhile except in small example programs.
One criticism is that checked exceptions encourage programmers to use an empty catch block (
catch (Exception e) {}
), which silently eats exceptions, rather than letting the exceptions propagate to a higher-level exception-handling routine. In some cases, however, exception chainingException chaining
Exception chaining, or exception wrapping, is an object-oriented programming technique of handling exceptions by re-throwing a caught exception after wrapping it inside a new exception. The original exception is saved as a property of the new exception...
can be applied instead, by re-throwing the exception in a wrapper exception. For example, if an object is changed to access a database instead of a file, an could be caught and re-thrown as an , since the caller may not need to know the inner workings of the object.
There are also differences between the two languages in treating the
try-finally
statement. The finally
block is always executed, even if the try
block contains control-passing statements like throw
or return
. In Java, this may result in unexpected behavior if the try
block is left by a return
statement with some value, and then the finally
block that is executed afterward is also left by a return
statement with a different value. C# resolves this problem by prohibiting any control-passing statements like return
or break
in the finally
block.A common reason for using
try-finally
blocks is to guard resource managing code, thus guaranteeing the release of precious resources in the finally block. C# features the using
statement as a syntactic shorthand for this common scenario, in which the Dispose
method of the object of the using
is always called.A rather subtle difference is the moment a stack trace is created when an exception is being thrown. In Java, the stack trace is created in the moment the exception is created.
The exception in the statement above will always contain the constructor's stack-trace - no matter how often foo is called.
In C# on the other hand, the stack-trace is created the moment "throw" is executed.
In the code above, the exception will contain the stack-trace of the first throw-line. When catching an exception, there are two options in case the exception should be rethrown:
throw
will just rethrow the original exception with the original stack, while throw e
would have created a new stack trace.Finally blocks
Java allows flow of control to leave thefinally
block of a try
statement, regardless of the way it was entered. This can cause another control flow statement (such as return
) to be terminated mid-execution. For example:In the above code, the
return
statement within try
block causes control to leave it, and therefore finally
block is executed before the actual return happens. However, finally
block itself performs a return as well; thus, the original return that caused it to be entered is not actually executed, and the above method returns 1 rather than 0.C# does not allow any statements which allow control flow to leave the
finally
block prematurely, except for throw
. In particular, return
is not allowed at all, goto
is not allowed if the target label is outside the finally
block, and continue
and break
are not allowed if the nearest enclosing loop is outside the finally
block.Lower level code
The Java Native InterfaceJava Native Interface
The Java Native Interface is a programming framework that enables Java code running in a Java Virtual Machine to call and to be called by native applications and libraries written in other languages such as C, C++ and assembly.-Purpose and features:JNI enables one to write native methods to...
(JNI) feature allows Java programs to call non-Java code. However, JNI does require the code being called to follow several conventions and imposes 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++. Java Native Access
Java Native Access
Java Native Access provides Java programs easy access to native shared libraries without using the Java Native Interface. JNA's design aims to provide native access in a natural way with a minimum of effort...
(JNA) allows easier calling of native code that only requires writing Java code, but comes at a performance cost.
In addition, third party libraries provide for Java-COM
Component Object Model
Component Object Model is a binary-interface standard for software componentry introduced by Microsoft in 1993. It is used to enable interprocess communication and dynamic object creation in a large range of programming languages...
bridging, e.g. JACOB (free
Free software
Free software, software libre or libre software is software that can be used, studied, and modified without restriction, and which can be copied and redistributed in modified or unmodified form either without restriction, or with restrictions that only ensure that further recipients can also do...
), and J-Integra for COM (proprietary
Proprietary software
Proprietary software is computer software licensed under exclusive legal right of the copyright holder. The licensee is given the right to use the software under certain conditions, while restricted from other uses, such as modification, further distribution, or reverse engineering.Complementary...
).
.NET Platform Invoke (P/Invoke
Platform Invocation Services
Platform Invocation Services, commonly referred to as P/Invoke, is a feature of Common Language Infrastructure implementations, like Microsoft's Common Language Runtime, that enables managed code to call native code.-Explicit:...
) offers the same capability by allowing calls from C# to what Microsoft refers to as unmanaged code. Through metadata attributes the programmer can control exactly how the parameters and results are marshalled
Marshalling (computer science)
In computer science, marshalling is the process of transforming the memory representation of an object to a data format suitable for storage or transmission...
, thus avoiding the need for extra adaption code. P/Invoke allows almost complete access to procedural APIs (such as Win32 or POSIX), but limited access to C++ class libraries.
In addition, .NET Framework also provides a .NET-COM bridge, allowing access to COM components as if they were native .NET objects.
C# also allows the programmer to disable the normal type-checking and other safety features of the CLR
Common Language Runtime
The Common Language Runtime is the virtual machine component of Microsoft's .NET framework and is responsible for managing the execution of .NET programs. In a process known as just-in-time compilation, the CLR compiles the intermediate language code known as CIL into the machine instructions...
, which then enables the use of pointer variables. When using this feature, 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. An assembly (program or library) 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.Runtime environments
Java (the programming language) is designed to execute on the Java platform via the Java Runtime Environment (JRE). The Java platform includes the Java Virtual MachineJava Virtual Machine
A Java virtual machine is a virtual machine capable of executing Java bytecode. It is the code execution component of the Java software platform. Sun Microsystems stated that there are over 4.5 billion JVM-enabled devices.-Overview:...
(JVM) as well as a common set of libraries. The JRE was originally designed to support interpreted execution with final compilation as an option. Most JRE environments execute fully or at least partially compiled programs, possibly with adaptive optimization
Adaptive optimization
Adaptive optimization is a technique in computer science that performs dynamic recompilation of portions of a program based on the current execution profile. With a simple implementation, an adaptive optimizer may simply make a trade-off between Just-in-time compilation and interpreting instructions...
. The Java compiler produces Java bytecode
Java bytecode
Java bytecode is the form of instructions that the Java virtual machine executes. Each bytecode opcode is one byte in length, although some require parameters, resulting in some multi-byte instructions. Not all of the possible 256 opcodes are used. 51 are reserved for future use...
. Upon execution the bytecode is loaded by the Java runtime and either interpreted directly or compiled to machine instructions and then executed.
C# is designed to execute on the Common Language Runtime
Common Language Runtime
The Common Language Runtime is the virtual machine component of Microsoft's .NET framework and is responsible for managing the execution of .NET programs. In a process known as just-in-time compilation, the CLR compiles the intermediate language code known as CIL into the machine instructions...
(CLR). The CLR is designed to execute fully compiled code. The C# compiler produces Common Intermediate Language
Common Intermediate Language
Common Intermediate Language is the lowest-level human-readable programming language defined by the Common Language Infrastructure specification and is used by the .NET Framework and Mono...
instructions. Upon execution the runtime loads this code and compiles to machine instructions on the target architecture.
Java
Java is older than C# and has built up a large and highly active user base, becoming the lingua francaLingua franca
A lingua franca is a language systematically used to make communication possible between people not sharing a mother tongue, in particular when it is a third language, distinct from both mother tongues.-Characteristics:"Lingua franca" is a functionally defined term, independent of the linguistic...
in many modern branches of computer science, particularly areas which involve networking
Computer network
A computer network, often simply referred to as a network, is a collection of hardware components and computers interconnected by communication channels that allow sharing of resources and information....
. Java dominates programming courses at high school and college level in the United States, and there are currently more Java books than C# books. Java's maturity and popularity have ensured more third party Java APIs and libraries (many of them open source) than C#.
An occasionally voiced criticism of the Java language is that it evolves slowly, lacking some features which make fashionable programming patterns and methodologies easier. Some critics suggest that the designers of C# may pander too quickly to current trends in programming, thus lacking focus and simplicity. 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 prove to be dead ends.
These trends have been broken with the Java 5.0 release, which introduced several new major language features: a foreach
Foreach
For each is a computer language idiom for traversing items in a collection. Foreach is usually used in place of a standard for statement. Unlike other for loop constructs, however, foreach loops usually maintain no explicit counter: they essentially say "do this to everything in this set",...
construct, autoboxing, methods with variable number of parameters (varargs), enumerated type
Enumerated type
In computer programming, an enumerated type is a data type consisting of a set of named values called elements, members or enumerators of the type. The enumerator names are usually identifiers that behave as constants in the language...
s, generic types
Generic programming
In a broad definition, generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters...
, and annotation
Annotation
An annotation is a note that is made while reading any form of text. This may be as simple as underlining or highlighting passages.Annotated bibliographies give descriptions about how each source is useful to an author in constructing a paper or argument...
s. With the exception of Generics, C# included all these features from its beginning, some under different names. Proposals and specifications for the new features had been worked on in the Java community for a considerable time before they were introduced. Indeed, some had been in gestation since before C#'s initial release (e.g., work on Generics formally began in May 1999), such was the Java community's conservatism at that time.
Problem-specific 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 that address themselves specifically toward 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.
As of 2008 debate continued over the inclusion of closures
Closure (computer science)
In computer science, a closure is a function together with a referencing environment for the non-local variables of that function. A closure allows a function to access variables outside its typical scope. Such a function is said to be "closed over" its free variables...
and properties
Property (programming)
A property, in some object-oriented programming languages, is a special sort of class member, intermediate between a field and a method. Properties are read and written like fields, but property reads and writes are translated to get and set method calls...
into the language syntax for Java 7.
C#
By contrast, C# is a relatively new language. Microsoft has studied existing languages such as Java and Object Pascal, and has changed some aspects of the language and runtime environment in response to perceived failures and difficulties with its predecessors. C# accommodates constructs more commonly found in languages such as C++C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
, Delphi (the design of which was Anders Hejlsberg's
Anders Hejlsberg
Anders Hejlsberg is a prominent Danish software engineer who co-designed several popular and commercially successful programming languages and development tools...
principal job when he was at Borland
Borland
Borland Software Corporation is a software company first headquartered in Scotts Valley, California, Cupertino, California and finally Austin, Texas. It is now a Micro Focus subsidiary. It was founded in 1983 by Niels Jensen, Ole Henriksen, Mogens Glad and Philippe Kahn.-The 1980s:...
), and, in recent C# versions, borrows from dynamic scripting languages such as Ruby and Python.
C# 3.0 adds SQL
SQL
SQL is a programming language designed for managing data in relational database management systems ....
-like language integrated queries
Language Integrated Query
Language Integrated Query is a Microsoft .NET Framework component that adds native data querying capabilities to .NET languages, although ports exist for Java, PHP and JavaScript....
suited for querying data from collections, database
Database
A database is an organized collection of data for one or more purposes, usually in digital form. The data are typically organized to model relevant aspects of reality , in a way that supports processes requiring this information...
s or XML
XML
Extensible Markup Language is a set of rules for encoding documents in machine-readable form. It is defined in the XML 1.0 Specification produced by the W3C, and several other related specifications, all gratis open standards....
documents, building upon general-purpose language features, including lambda expression
Lambda expression
Lambda expression may refer to:*Anonymous function*Lambda calculus#Definition...
s and extension method
Extension method
An Extension method is a new language feature of C# starting with the 3.0 specification, as well as Visual Basic.NET starting with 9.0 and Oxygene with 2.0. Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying...
s, to allow queries to be expressed and optimized for user types.
Before creating C#, Microsoft implemented a modified Java environment, called J++
Visual J++
Visual J++ was Microsoft's specific implementation of Java. Syntax, keywords, and grammatical conventions were the same as Java's. Microsoft discontinued support of J++ in January 2004, replacing it to a certain extent with J# and C#....
, adding new features in a manner which was in direct contravention to the standards and conventions that ensure the platform neutrality which lies at the heart of Java. This violated the license agreement Microsoft had signed, requiring that standards and specifications be strictly adhered to in return for using the Java name and brand logos. Sun Microsystems sued, and in settling the suit, Microsoft agreed to discontinue J++. (The settlement allowed other existing Java-using Microsoft products to continue such use for seven years.) With the release of the .NET framework (and C#), the project was revived in the form of J#
J Sharp
Visual J# |sharp]]') programming language is a discontinued transitional language for programmers of Java and Visual J++ languages, so they may use their existing knowledge and applications on .NET Framework....
.
See also
- Comparison of C# and VB.NETComparison of C sharp and Visual Basic .NETC# and Visual Basic .NET are the two primary languages used to program on the .NET Framework.-Language history:C# and VB.NET are syntactically very different languages with very different history...
- Comparison of Java and C++Comparison of Java and C++This is a comparison of the Java programming language with the C++ programming language.- Design aims :The differences between the C++ and Java programming languages can be traced to their heritage, as they have different design goals....
- Java programming languageJava (programming language)Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
- Comparison of the Java and .Net platformsComparison of the Java and .NET platforms- Standardization :The two platforms, their programming libraries, their binary formats, and their runtime environments have largely been governed by very different means.The .NET platform as a whole has not been standardized...
External links
- Moving to C# and the .NET Framework at MSDN
- C# and Java: Comparing Programming Languages at MSDN
- A Comparison of C# and Java
- Java vs. C# - Code for Code Comparison
- Nine Language Performance Round-up
- Java and C-Sharp Compared
- MSDNMicrosoft Developer NetworkThe Microsoft Developer Network is the portion of Microsoft responsible for managing the firm's relationship with developers and testers: hardware developers interested in the operating system , developers standing on the various OS platforms, developers using the API and scripting languages of...
: The C# Programming Language for Java Developers - Standard ECMA-334 C# Language specification
- Java Language Specification (Sun)