HOME

TheInfoList



OR:

This article compares two
programming language A programming language is a system of notation for writing computer programs. Most programming languages are text-based formal languages, but they may also be graphical. They are a kind of computer language. The description of a programming ...
s: C# with
Java Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's mo ...
. While the focus of this article is mainly the languages and their features, such a comparison will necessarily also consider some features of platforms and
libraries A library is a collection of Document, materials, books or media that are accessible for use and not just for display purposes. A library provides physical (hard copies) or electronic media, digital access (soft copies) materials, and may be a ...
. For a more detailed comparison of the platforms, see
Comparison of the Java and .NET platforms Comparison of the Java and .NET platforms. Legal issues .NET The Mono project aims to avoid infringing on any patents or copyrights and, to the extent that they are successful, the project can be safely distributed and used under the GPL. On N ...
. C# and Java are similar languages that are typed statically, strongly, and manifestly. Both are
object-oriented Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code. The data is in the form of fields (often known as attributes or ''properties''), and the code is in the form of ...
, and designed with semi-
interpretation Interpretation may refer to: Culture * Aesthetic interpretation, an explanation of the meaning of a work of art * Allegorical interpretation, an approach that assumes a text should not be interpreted literally * Dramatic Interpretation, an event ...
or runtime
just-in-time compilation In computing, just-in-time (JIT) compilation (also dynamic translation or run-time compilations) is a way of executing computer code that involves compilation during execution of a program (at run time) rather than before execution. This may co ...
, and both are curly brace languages, like C and
C++ C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
.


Types


Unified type system

Both languages are statically typed with class-based object orientation. In Java the
primitive types In computer science, primitive data types are a set of basic data types from which all other data types are constructed. Specifically it often refers to the limited set of data representations in use by a particular processor, which all compiled pr ...
are special in that they are not
object-oriented Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code. The data is in the form of fields (often known as attributes or ''properties''), and the code is in the form of ...
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 type In computer programming, data types can be divided into two categories: value types (or by-value types) and reference types (or by-reference types). Value types are completely represented by their meaning, while reference types are references to ano ...
s all derive from a common root type. C# has a unified
type system In computer programming, a type system is a logical system comprising a set of rules that assigns a property called a type to every "term" (a word, phrase, or other set of symbols). Usually the terms are various constructs of a computer progra ...
in which all types (besides unsafe pointers) 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 delegates. This allows C#, unlike Java, to support objects with encapsulation that 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. Both languages support many built-in types that are copied and passed by value rather than by reference. Java calls these types
primitive type In computer science, primitive data types are a set of basic data types from which all other data types are constructed. Specifically it often refers to the limited set of data representations in use by a particular processor, which all compiled pr ...
s, while they are called ''simple types'' in C#. The primitive/simple types typically have native support from the underlying processor architecture. The C# simple types implement several
interfaces Interface or interfacing may refer to: Academic journals * ''Interface'' (journal), by the Electrochemical Society * '' Interface, Journal of Applied Linguistics'', now merged with ''ITL International Journal of Applied Linguistics'' * '' Int ...
and consequently offer many methods directly on instances of the types, even on the literals. The C# type names are also merely ''aliases'' for
Common Language Runtime The Common Language Runtime (CLR), the virtual machine component of Microsoft .NET Framework, manages the execution of .NET programs. Just-in-time compilation converts the managed code (compiled intermediate language code) into machine instru ...
(CLR) types. The C# System.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 primitive types. Instead, methods that operate on primitive values are offered through companion primitive 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 Long type is a
reference type In computer programming, data types can be divided into two categories: value types (or by-value types) and reference types (or by-reference types). Value types are completely represented by their meaning, while reference types are references to ano ...
that wraps the primitive long type. They are ''not'' the same type, however.


Data types


Numeric types


= Signed integers

= Both Java and C# support signed integers with bit widths of 8, 16, 32 and 64 bits. They use the same name/aliases for the types, except for the 8-bit integer that is called a byte in Java and a sbyte (signed byte) in C#.


= Unsigned integers

= C# supports unsigned in addition to the signed integer types. The unsigned types are byte, ushort, uint and ulong for 8, 16, 32 and 64 bit widths, respectively. Unsigned arithmetic operating on the types are supported as well. For example, adding two unsigned integers (uints) still yields a uint as a result; not a long or signed integer. Java does not feature unsigned integer types. In particular, Java lacks a primitive type for an unsigned
byte The byte is a unit of digital information that most commonly consists of eight bits. Historically, the byte was the number of bits used to encode a single character of text in a computer and for this reason it is the smallest addressable uni ...
. Instead, Java's byte type is sign extended, which is a common source of bugs and confusion. Unsigned integers were left out of Java deliberately because
James Gosling James Gosling (born May 19, 1955) is a Canadian computer scientist, best known as the founder and lead designer behind the Java programming language. Gosling was elected a member of the National Academy of Engineering in 2004 for the conception ...
believed that programmers would not understand how unsigned arithmetic works.
In programming language design, one of the standard problems is that the language grows so complex that nobody can understand it. One of the little experiments I tried was asking people about the rules for unsigned arithmetic in C. It turns out nobody understands how unsigned arithmetic in C works. There are a few obvious things that people understand, but many people don't understand it.


= High-precision decimal numbers

= C# has a type and literal notation for high-precision (28 decimal digits) decimal arithmetic that is appropriate for financial and monetary calculations. Contrary to the float and double data types, decimal fractional numbers such as 0.1 can be represented exactly in the decimal representation. In the float and double representations, such numbers often have non-terminating binary expansions, making those representations more prone to round-off errors. 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 that must be manipulated using the type methods. See more about arbitrary-size/precision numbers
below Below may refer to: *Earth * Ground (disambiguation) *Soil *Floor * Bottom (disambiguation) *Less than *Temperatures below freezing *Hell or underworld People with the surname *Ernst von Below (1863–1955), German World War I general *Fred Below ...
.


Advanced numeric types

Both languages offer library-defined
arbitrary-precision arithmetic In computer science, arbitrary-precision arithmetic, also called bignum arithmetic, multiple-precision arithmetic, or sometimes infinite-precision arithmetic, indicates that calculations are performed on numbers whose digits of precision are li ...
types for arbitrary-size integers and decimal point calculations. Only Java has a data type for arbitrary precision decimal point calculations. Only C# has a type for working with
complex number In mathematics, a complex number is an element of a number system that extends the real numbers with a specific element denoted , called the imaginary unit and satisfying the equation i^= -1; every complex number can be expressed in the fo ...
s. In both languages, the number of operations that can be performed on the advanced numeric types is limited compared to the built-in
IEEE 754 The IEEE Standard for Floating-Point Arithmetic (IEEE 754) is a technical standard for floating-point arithmetic established in 1985 by the Institute of Electrical and Electronics Engineers (IEEE). The standard addressed many problems found ...
floating point types. For instance, none of the arbitrary-size types support
square root In mathematics, a square root of a number is a number such that ; in other words, a number whose '' square'' (the result of multiplying the number by itself, or  ⋅ ) is . For example, 4 and −4 are square roots of 16, because . ...
or
logarithm In mathematics, the logarithm is the inverse function to exponentiation. That means the logarithm of a number  to the base  is the exponent to which must be raised, to produce . For example, since , the ''logarithm base'' 10 ...
s. C# allows library-defined types to be integrated with existing types and operators by using custom implicit/explicit conversions and operator overloading. See example in section '' Integration of library-defined types''


Characters

Both languages feature a native char (character) datatype as a simple type. Although the char type can be used with bit-wise operators, this is performed by promoting the char value to an integer value before the operation. Thus, the result of a bitwise operation is a numeric type, not a character, in both languages.


Built-in compound data types

Both languages treat strings as ( immutable) objects of reference type. In both languages, the type contains several methods to manipulate strings, parse, format, etc. In both languages
regular expression A regular expression (shortened as regex or regexp; sometimes referred to as rational expression) is a sequence of characters that specifies a search pattern in text. Usually such patterns are used by string-searching algorithms for "find" ...
s are considered an external feature and are 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, whereas the C# System.DateTime is a struct value type. C# additionally defines a TimeSpan type for working with time periods. Both languages support date and time arithmetic according to different cultures.


User-defined value type (struct)

C# allows the programmer to create user-defined
value type In computer programming, data types can be divided into two categories: value types (or by-value types) and reference types (or by-reference types). Value types are completely represented by their meaning, while reference types are references to an ...
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 Boxed may refer to: * Boxed.com, a wholesale on-line shopping site. * Boxed (Eurythmics), ''Boxed'' (Eurythmics), an eight album box set * Boxed (Mike Oldfield album), ''Boxed'' (Mike Oldfield album) * Boxed warning, a warning that appears on Unite ...
), 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 In computer programming languages, the term default constructor can refer to a constructor that is automatically generated by the compiler in the absence of any programmer-defined constructors (e.g. in Java), and is usually a nullary constructor. I ...
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 In computer programming, a virtual method table (VMT), virtual function table, virtual call table, dispatch table, vtable, or vftable is a mechanism used in a programming language to support dynamic dispatch (or run-time method binding). Whe ...
s, and because of that (and the fixed memory footprint), they are implicitly sealed. However, value types ''can'' (and frequently do) implement
interfaces Interface or interfacing may refer to: Academic journals * ''Interface'' (journal), by the Electrochemical Society * '' Interface, Journal of Applied Linguistics'', now merged with ''ITL International Journal of Applied Linguistics'' * '' Int ...
. For example, the built-in integer types implement several
interfaces Interface or interfacing may refer to: Academic journals * ''Interface'' (journal), by the Electrochemical Society * '' Interface, Journal of Applied Linguistics'', now merged with ''ITL International Journal of Applied Linguistics'' * '' Int ...
. Apart from the built-in primitive types, Java does not include the concept of value types.


Enumerations

Both languages define enumerations, but they are implemented in fundamentally different ways. As such, enumerations are one area where tools designed to automatically translate code between the two languages (such as Java to C# converters) fail. C# has implemented enumerations in a manner similar to C, that is as wrappers around the bit-flags implemented in primitive integral types (int, byte, short, etc.). This has performance benefits and improves interaction with C/C++ compiled code, but provides fewer features and can lead to bugs if low-level value types are directly cast to an enumeration type, as is allowed in the C# language. Therefore, it is seen as
syntactic sugar In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language "sweeter" for human use: things can be expressed more clearly, more concisely, or in an ...
. In contrast, Java implements enumerations as full featured collection of instances, requiring more memory and not aiding interaction with C/C++ code, but providing additional features in reflection and intrinsic behavior. The implementation in each language is described in the table below. In both C# and Java, programmers can use enumerations in a
switch statement In computer programming languages, a switch statement is a type of selection control mechanism used to allow the value of a variable or expression to change the control flow of program execution via search and map. Switch statements function s ...
without conversion to a string or primitive integer type. However, C# disallows implicit fall-through unless the case statement does not contain any code, as it is a common cause of hard-to-find bugs. Fall-through must be explicitly declared using a goto statement.


Delegates, method references

C# implements object-oriented method pointers in the form of delegates. A delegate is a special type that can capture a 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 Event may refer to: Gatherings of people * Ceremony, an event of ritual significance, performed on a special occasion * Convention (meeting), a gathering of individuals engaged in some common interest * Event management, the organization of ev ...
, 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, alternative mechanisms are used. The
wrapper pattern In software engineering, the adapter pattern is a software design pattern (also known as wrapper, an alternative naming shared with the decorator pattern) that allows the interface of an existing class to be used as another interface. It is often ...
, which resembles the delegates of C# in that it allows the client to access one or more client-defined methods through a known
interface Interface or interfacing may refer to: Academic journals * ''Interface'' (journal), by the Electrochemical Society * '' Interface, Journal of Applied Linguistics'', now merged with ''ITL International Journal of Applied Linguistics'' * '' Int ...
, is one such mechanism. Another is the use of
adapter An adapter or adaptor is a device that converts attributes of one electrical device or system to those of an otherwise incompatible device or system. Some modify power or signal attributes, while others merely adapt the physical form of one c ...
objects using inner classes, which the designers of Java argued are a better solution than bound method references. See also example C# delegates and equivalent Java constructs.


Lifted (nullable) types

C# allows value/primitive/simple types to be "lifted" to allow the special null value in addition to the type's native values. A type is lifted by adding a ? suffix to the type name; this is equivalent to using the Nullable
generic Generic or generics may refer to: In business * Generic term, a common name used for a range or class of similar things not protected by trademark * Generic brand, a brand for a product that does not have an associated brand or trademark, other ...
type, where T is the type to be lifted. 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 there is no object to be unboxed – and thus 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. 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 logic In logic, a three-valued logic (also trinary logic, trivalent, ternary, or trilean, sometimes abbreviated 3VL) is any of several many-valued logic systems in which there are three truth values indicating ''true'', ''false'' and some indeterminat ...
thus keeping impedance with SQL. 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 bound dynamic type that supports no-reflection dynamic invocation, interoperability with dynamic languages, and 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 Reflection or reflexion may refer to: Science and technology * Reflection (physics), a common wave phenomenon ** Specular reflection, reflection from a smooth surface *** Mirror image, a reflection in a mirror or in water ** Signal reflection, in ...
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
XML Extensible Markup Language (XML) is a markup language and file format for storing, transmitting, and reconstructing arbitrary data. It defines a set of rules for encoding documents in a format that is both human-readable and machine-readable. T ...
or
XHTML Extensible HyperText Markup Language (XHTML) is part of the family of XML markup languages. It mirrors or extends versions of the widely used HyperText Markup Language (HTML), the language in which Web pages are formulated. While HTML, prior ...
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 must be used. The
Java virtual machine A Java virtual machine (JVM) is a virtual machine that enables a computer to run Java programs as well as programs written in other languages that are also compiled to Java bytecode. The JVM is detailed by a specification that formally describe ...
platform does have multiple dynamic languages implemented on it, but there is no common standard for how to pass objects between languages. Usually this involves some form of reflection or reflection-like API. As an example of how to use JavaFX objects from Java. * For creating and interacting with objects entirely at runtime, e.g., interaction with a document object model abstraction, a specific abstraction API must be used. See also example #Interoperability with dynamic languages.


Pointers

Java precludes pointers and pointer-arithmetic within the Java runtime environment. The Java language designers reasoned that pointers are one of the main features that enable programmers to put bugs in their code and chose not to support them. Java does not allow for directly passing and receiving objects/structures to/from the underlying operating system and thus does not need to model objects/structures to such a specific memory layout, layouts that frequently would involve pointers. Java's communication with the underlying operating system is instead based upon
Java Native Interface In software design, the Java Native Interface (JNI) is a foreign function interface programming framework that enables Java code running in a Java virtual machine (JVM) to call and be called by native applications (programs specific to a hardwa ...
(JNI) where communication with/adaptation to an underlying operating system is handled through an external ''glue'' layer. While C# does allow use of
pointers Pointer may refer to: Places * Pointer, Kentucky * Pointers, New Jersey * Pointers Airport, Wasco County, Oregon, United States * The Pointers, a pair of rocks off Antarctica People with the name * Pointer (surname), a surname (including a lis ...
and corresponding pointer arithmetic, the C# language designers had the same concerns that pointers could potentially be used to bypass the strict rules for object access. Thus, C# by default also precludes pointers. However, because pointers are needed when calling many native functions, pointers are allowed in an explicit ''unsafe'' mode. Code blocks or methods that use the pointers must be marked with the unsafe keyword to be able to use pointers, and the compiler requires the /unsafe switch to allow compiling such code. Assemblies that are compiled using the /unsafe switch are marked as such and may only execute if explicitly trusted. This allows using pointers and pointer arithmetic to directly pass and receive objects to/from the operating system or other native APIs using the native memory layout for those objects while also isolating such potentially unsafe code in specifically trusted assemblies.


Reference types

In both languages
references Reference is a relationship between objects in which one object designates, or acts as a means by which to connect to or link to, another object. The first object in this relation is said to ''refer to'' the second object. It is called a ''name'' ...
are a central concept. All instances of classes are ''by reference''. While not directly evident in the language syntax ''per se'', both languages support the concept of ''weak'' references. An instance that is only referenced by weak references is eligible for garbage collection just as if there were no references at all. In both languages this feature is exposed through the associated libraries, even though it is really a core runtime feature. Along with weak references, Java has ''
soft reference A soft reference is a reference that is garbage-collected less aggressively. The 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. In order from ...
s''. They are much like weak references, but the JVM will not deallocate softly-referenced objects until the memory is needed.


Arrays and collections

Arrays and
collections Collection or Collections may refer to: * Cash collection, the function of an accounts receivable department * Collection (church), money donated by the congregation during a church service * Collection agency, agency to collect cash * Collection ...
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 Locality may refer to: * Locality (association), an association of community regeneration organizations in England * Locality (linguistics) * Locality (settlement) * Suburbs and localities (Australia), in which a locality is a geographic subdivis ...
(as there is one pointer dereference instead of one for every dimension of the array, as it 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 difference 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. However, Java provides a syntactic construct for allocating a 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 that includes various ordered and unordered types of lists, maps/dictionaries, sets, etc. Java also supports the syntax of C/C++:


Expressions and operators


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 In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language "sweeter" for human use: things can be expressed more clearly, more concisely, or in an ...
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 task is accomplished by the primitive wrapper classes.
Secondly, in Java an extra cast is needed whenever one tries to directly
dereference In computer programming, the dereference operator or indirection operator, sometimes denoted by "*" (i.e. an asterisk), is a unary operator (i.e. one with a single operand) found in C-like languages that include pointer variables. It operates ...
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 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 or generics may refer to: In business * Generic term, a common name used for a range or class of similar things not protected by trademark * Generic brand, a brand for a product that does not have an associated brand or trademark, other ...
(see
below Below may refer to: *Earth * Ground (disambiguation) *Soil *Floor * Bottom (disambiguation) *Less than *Temperatures below freezing *Hell or underworld People with the surname *Ernst von Below (1863–1955), German World War I general *Fred Below ...
).


Statements


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 Interface or interfacing may refer to: Academic journals * ''Interface'' (journal), by the Electrochemical Society * '' Interface, Journal of Applied Linguistics'', now merged with ''ITL International Journal of Applied Linguistics'' * '' Int ...
) some minor differences exist. Java is explicit about extending classes and implementing
interfaces Interface or interfacing may refer to: Academic journals * ''Interface'' (journal), by the Electrochemical Society * '' Interface, Journal of Applied Linguistics'', now merged with ''ITL International Journal of Applied Linguistics'' * '' Int ...
, while C# infers this from the kind of types a new class/
interface Interface or interfacing may refer to: Academic journals * ''Interface'' (journal), by the Electrochemical Society * '' Interface, Journal of Applied Linguistics'', now merged with ''ITL International Journal of Applied Linguistics'' * '' Int ...
derives from. C# supports more features than Java, which to some extent is also evident in the syntax that 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 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 that 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 that 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 four-step solution: 1) Introducing a compiler switch that 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. 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.


Object-oriented programming

Both C# and Java are designed from the ground up as
object-oriented Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code. The data is in the form of fields (often known as attributes or ''properties''), and the code is in the form of ...
languages using dynamic dispatch, with syntax similar to
C++ C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
(C++ in turn derives from C). Neither language is a superset of C or C++, however.


Partial class

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 keyword partial. 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
user interface In the industrial design field of human–computer interaction, a user interface (UI) is the space where interactions between humans and machines occur. The goal of this interaction is to allow effective operation and control of the machine f ...
(UI) 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, the instance of the embracing outer class must be named. 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 delegates; see
event handling In programming and software design, an event is an action or occurrence recognized by software, often originating asynchronously from the external environment, that may be handled by the software. Computer events can be generated or triggered ...
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''.


Event

C# multicast-delegates are used with ''events''. Events provide support for
event-driven programming In computer programming, event-driven programming is a programming paradigm in which the flow of the program is determined by events such as user actions (mouse clicks, key presses), sensor outputs, or message passing from other programs or thr ...
and are an implementation of the
observer pattern In software design and engineering, the observer pattern is a software design pattern in which an object, named the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by ca ...
. To support this there is a specific syntax to define events in classes, and operators to register, unregister or combine event handlers. See
here Here is an adverb that means "in, on, or at this place". It may also refer to: Software * Here Technologies, a mapping company * Here WeGo (formerly Here Maps), a mobile app and map website by Here Television * Here TV (formerly "here!"), a ...
for information about how events are implemented in Java.


Operator overloading and conversions

Operator overloading In computer programming, operator overloading, sometimes termed ''operator ad hoc polymorphism'', is a specific case of polymorphism, where different operators have different implementations depending on their arguments. Operator overloading i ...
and user-defined casts are separate features that 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. Unlike C++, C# does restrict the use of operator overloading, prohibiting it for the operators new, ( ), , , , &&, =, and any variations of compound statements like +=. But compound operators will call overloaded simple operators, like -= calling - and =. Java does not include operator overloading, nor custom conversions in order to prevent abuse of the feature and to keep the language simple.


Indexer

C# also includes ''indexers'' that 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[] that uses one or more parameters (indexes); the indices can be objects of any type: myList = 5; string name = xmlNode.Attributes name" orders = customerMap heCustomer Java does not include indexers. The common Java pattern involves writing explicit getters and setters where a C# programmer would use an indexer.


Fields and initialization


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 (that 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.


Resource disposal

Both languages mainly use
garbage collection Waste collection is a part of the process of waste management. It is the transfer of solid waste from the point of use and disposal to the point of treatment or landfill. Waste collection also includes the curbside collection of recyclabl ...
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 must 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 that will automatically invoke the disposal/close methods on those interfaces.


Methods


Extension methods and default 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 must be declared static and defined within a purely static class. The method must obey any member access restriction like any other method external to the class; thus static methods cannot break object encapsulation. The "extension" is only active within scopes where the namespace of the static host class has been imported. Since Java 8, Java has a similar feature called ''default methods'', which are methods with a body declared on interfaces. As opposed to C# extension methods, Java default methods are instance methods on the interface that declare them. Definition of default methods in classes that implement the interface is optional: If the class does not define the method, the default definition is used instead. Both the C# extension methods and the Java default methods allow a class to override the default implementation of the extension/default method, respectively. In both languages this override is achieved by defining a method on the class that should use an alternate implementation of the method. C# scope rules defines that if a matching method is found on a class, it takes precedence over a matching extension method. In Java any class declared to implement an interface with default method is assumed to have the default methods implementions, ''unless'' the class implements the method itself.


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 several restrictions on the signature. The restrictions ensure that if a definition is not 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 method 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.


Virtual methods

''Methods'' in C# are non- virtual by default, and must 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 In computer programming, a virtual method table (VMT), virtual function table, virtual call table, dispatch table, vtable, or vftable is a mechanism used in a programming language to support dynamic dispatch (or run-time method binding). Whe ...
. However, some JVM implementations, including the Oracle 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 In object-oriented programming, inheritance is the mechanism of basing an object or class upon another object ( prototype-based inheritance) or class ( class-based inheritance), retaining similar implementation. Also defined as deriving new classe ...
' 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 In object-oriented programming, inheritance is the mechanism of basing an object or class upon another object ( prototype-based inheritance) or class ( class-based inheritance), retaining similar implementation. Also defined as deriving new classe ...
, 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 is intended to override an inherited method, the override keyword must be specified. Otherwise, the method will "hide" the inherited method. If the keyword is absent, compiler warning to this effect is issued, which can be silenced by specifying the new keyword. This avoids the problem that can arise from a base class being extended with a non-private method (i.e. an inherited part of the namespace) whose signature is already in use by a derived class. Java has a similar compiler check in the form of the @Override method annotation, but it is not compulsory, and in its absence, most compilers will not provide comment (but the method will be overridden).


Constant/immutable parameters

In Java, it is possible to prevent reassignment of a local variable or method parameter by using the keyword. Applying this keyword to a primitive type variable causes the variable to become immutable. However, applying to a reference type variable only prevents that another object is assigned to it. It will not prevent the data contained by the object from being mutated. As of C#7, it is possible to prevent reassignment of a method parameter by using the in keyword, however this keyword cannot be used on local variables. As with Java, applying in to a parameter only prevents the parameter from being reassigned to a different value. It is still possible to mutate the data contained by the object. Both languages do not support essential feature of
const-correctness In some programming languages, const is a type qualifier (a keyword applied to a data type) that indicates that the data is read-only. While this can be used to declare constants, in the C family of languages differs from similar constructs i ...
that exists in C/
C++ C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
, which makes a method constant. Java defines the word "constant" arbitrarily as a field. As a convention, these variable names are capital-only with words separated with an
underscore An underscore, ; also called an underline, low line, or low dash; is a line drawn under a segment of text. In proofreading, underscoring is a convention that says "set this text in italic type", traditionally used on manuscript or typescript ...
but the Java language doesn't insist on this. A parameter that is only is not considered as a constant, although it may be so in the case of a
primitive data type In computer science, primitive data types are a set of basic data types from which all other data types are constructed. Specifically it often refers to the limited set of data representations in use by a particular processor, which all compiled pr ...
or an immutable class, like a .


Generator methods

Any C# method declared as returning IEnumerable, IEnumerator 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 needed 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 In mathematics, the Fibonacci numbers, commonly denoted , form a sequence, the Fibonacci sequence, in which each number is the sum of the two preceding ones. The sequence commonly starts from 0 and 1, although some authors start the sequence from ...
. 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. See also example
Fibonacci sequence In mathematics, the Fibonacci numbers, commonly denoted , form a sequence, the Fibonacci sequence, in which each number is the sum of the two preceding ones. The sequence commonly starts from 0 and 1, although some authors start the sequence from ...
below.


Explicit interface implementation

C# also has ''explicit interface implementation'' that allows a class to specifically implement methods of an
interface Interface or interfacing may refer to: Academic journals * ''Interface'' (journal), by the Electrochemical Society * '' Interface, Journal of Applied Linguistics'', now merged with ''ITL International Journal of Applied Linguistics'' * '' Int ...
, 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. 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 that implements those interfaces. An implementation will by default implement a common method for all of the interfaces. If separate implementations are needed (because the methods 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 refactoring one or more of the interfaces to avoid name clashes.


Reference (in/out) parameters

The arguments of primitive types (e.g. int, double) to a method are passed by value in Java whereas objects are passed by reference. This means that a method operates on copies of the primitives passed to it instead of on the actual variables. On the contrary, the actual objects in some cases can be changed. In the following example, object String is not changed. Object of class 'a' is changed. In C#, it is possible to enforce a reference with the ref keyword, similar to C++ and in a sense to C. This feature of C# is particularly useful when one wants to create a method that returns more than one object. In Java trying to return multiple values from a method is unsupported unless a wrapper is used, in this case named "Ref".


Exceptions


Checked exceptions

Java supports
checked exceptions In computing and computer programming, exception handling is the process of responding to the occurrence of ''exceptions'' – anomalous or exceptional conditions requiring special processing – during the execution of a program. In general, an ...
(along with 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 a try-catch clause. Checked exceptions can encourage good programming practice, ensuring that all errors are dealt with. However
Anders Hejlsberg Anders Hejlsberg (, born 2 December 1960) is a Danish software engineer who co-designed several programming languages and development tools. He was the original author of Turbo Pascal and the chief architect of Delphi. He currently works for ...
, 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 swallows exceptions, rather than letting the exceptions propagate to a higher-level exception-handling routine. In some cases, however, exception chaining 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. However, not all programmers agree with this stance. James Gosling and others maintain that checked exceptions are useful, and misusing them has caused the problems. Silently catching exceptions is possible, yes, but it must be stated explicitly what to do with the exception, versus unchecked exceptions that allow doing nothing by default. It can be ignored, but code must be written explicitly to ignore it.


Try-catch-finally

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 In computing, a stack trace (also called stack backtrace or stack traceback) is a report of the active stack frames at a certain point in time during the execution of a program. When a program is run, memory is often dynamically allocated in two ...
is created when an exception is being thrown. In Java, the stack trace is created in the moment the exception is created. class Foo 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. class Foo 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 the finally 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: int foo() In the above code, the return statement within the try block causes control to leave it, and thus finally block is executed before the actual return happens. However, the finally block itself also performs a return. Thus, the original return that caused it to be entered is not executed, and the above method returns 1 rather than 0. Informally speaking, it ''tries'' to return 0 but ''finally'' returns 1. C# does not allow any statements that 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.


Generics

In the field of
generics Generic or generics may refer to: In business * Generic term, a common name used for a range or class of similar things not protected by trademark * Generic brand, a brand for a product that does not have an associated brand or trademark, other ...
the two languages show a superficial syntactical similarity, but they have deep underlying differences.


Type erasure versus reified generics

Generics in Java Generics are a facility of generic programming that were added to the Java programming language in 2004 within version J2SE 5.0. They were designed to extend Java's type system to allow "a type or method to operate on objects of various types whil ...
are a language-only construction; they are implemented only in the compiler. The generated classfiles include generic signatures only in 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 A Java virtual machine (JVM) is a virtual machine that enables a computer to run Java programs as well as programs written in other languages that are also compiled to Java bytecode. The JVM is detailed by a specification that formally describes ...
. Instead, generics classes and methods are transformed during compiling via a process termed
type erasure In programming languages, type erasure is the load-time process by which explicit type annotations are removed from a program, before it is executed at run-time. Operational semantics that do not require programs to be accompanied by types are c ...
. During this, 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 are a facility of generic programming that were added to the Java programming language in 2004 within version J2SE 5.0. They were designed to extend Java's type system to allow "a type or method to operate on objects of various types whil ...
). The Java language specification intentionally prohibits certain uses of generics; this is necessary to allow for implementing generics through
type erasure In programming languages, type erasure is the load-time process by which explicit type annotations are removed from a program, before it is executed at run-time. Operational semantics that do not require programs to be accompanied by types are c ...
, and to allow for migration compatibility. Research into adding reified generics to the Java platform is ongoing, as part of Project Valhalla. C# builds on support for generics from the virtual execution system, 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 compiling generics are verified for correctness, but code generation to ''implement'' 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 one type, as reference types can safely share the same implementations. This is merely for the purpose of ''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., List instead of List). 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 is allowed. Several third-party libraries implemented the basic collections in Java with backing primitive arrays to preserve the runtime and memory optimization that primitive types provide.


Migration compatibility

Java's type erasure design was motivated by a design requirement to achieve ''migration compatibility'' – not to be confused with
backward compatibility Backward compatibility (sometimes known as backwards compatibility) is a property of an operating system, product, or technology that allows for interoperability with an older legacy system, or with input designed for such a system, especiall ...
. 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 that 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 that 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 that 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 unsupported directly on classes but is supported through their implementation of variant interfaces. C# also has use-site covariance support for methods and delegates.


Functional programming


Closures

A closure is an inline function that captures variables from its lexical scope. C# supports closures as anonymous methods or lambda expressions with full-featured closure semantics. In Java, anonymous inner classes will remain the preferred way to emulate closures until Java 8 has become the new standard. This is a more verbose construction. This approach also has some differences compared to real closures, notably more controlled access to variables from the enclosing scopes: only final members can be referenced. Java 8, however introduces lambdas that fully inherit the current scope and, in fact, do not introduce a new scope. 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 access 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 mark which variables to make available, and in what state (possibly requiring boxing).


Lambdas and expression trees

C# and Java feature a special type of in-line closures 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 In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions tha ...
. C#, unlike Java, allows the use of lambda functions 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 Type inference refers to the automatic detection of the type of an expression in a formal language. These include programming languages and mathematical type systems, but also natural languages in some branches of computer science and linguistic ...
and what type of variable or parameter they are assigned or cast to. Lambdas and expression trees play key roles in Language Integrated Query (LINQ).


Metadata


Preprocessing, compilation and packaging


Namespaces and file contents

In C#,
namespace In computing, a namespace is a set of signs (''names'') that are used to identify and refer to objects of various kinds. A namespace ensures that all of a given set of objects have unique names so that they can be easily identified. Namespaces ...
s are similar to those in
C++ C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
. 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., 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. Both languages have a
static import Static import is a feature introduced in the Java programming language that allows members (fields and methods) which have been scoped within their container class as public static, to be used in Java code without specifying the class in which the ...
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 methods 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, Inc. (Sun for short) was an American technology company that sold computers, computer components, software, and information technology services and created the Java programming language, the Solaris operating system, ZFS, t ...
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.


Conditional compilation

Unlike Java, C# implements
conditional compilation In computer programming, conditional compilation is a compilation technique which results in an executable program that is able to be altered by changing specified parameters. This technique is commonly used when these alterations to the program ...
using
preprocessor directive In computer programming, a directive or pragma (from "pragmatic") is a language construct that specifies how a compiler (or other translator) should process its input. Directives are not part of the grammar of a programming language, and may vary ...
s. It also provides a Conditional
attribute Attribute may refer to: * Attribute (philosophy), an extrinsic property of an object * Attribute (research), a characteristic of an object * Grammatical modifier, in natural languages * Attribute (computing), a specification that defines a prope ...
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 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.


Threading and asynchronous features

Both languages include thread
synchronization Synchronization is the coordination of events to operate a system in unison. For example, the conductor of an orchestra keeps the orchestra synchronized or ''in time''. Systems that operate with all parts in synchrony are said to be synchronou ...
mechanisms as part of their language syntax.


Task-based parallelism for C#

With .NET Framework 4.0, a new task-based programming model was introduced to replace the existing event-based asynchronous model. The API is based around the Task and Task classes. Tasks can be composed and chained. By convention, every method that returns a Task should have its name postfixed with ''Async''. public static class SomeAsyncCode var t = SomeAsyncCode.GetContentAsync().ContinueWith((task) => ); t.Start(); In C# 5 a set of language and compiler extensions was introduced to make it easier to work with the task model. These language extensions included the notion of async methods and the await statement that make the program flow appear synchronous. public static class SomeAsyncCode var xmlDocument = await SomeAsyncCode.GetContentAsync(); // The Task will be started on call with await. From this
syntactic sugar In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language "sweeter" for human use: things can be expressed more clearly, more concisely, or in an ...
the C# compiler generates a state-machine that handles the necessary continuations without developers having to think about it.


Task-based parallelism for Java

Java supports threads since JDK 1.0. Java offers a high versatility for running threads, often called tasks. This is done by implementing a functional interface (a java.lang.Runnable interface) defining a single void no-args method as demonstrated in the following example: var myThread = new Thread(() -> ); myThread.start(); Similar to C#, Java has a higher level mechanism for working with threads. Executors can execute asynchronous tasks and also manage a group of subprocesses. All the threads of an ExecutorServices instance are handled in a
pool Pool may refer to: Water pool * Swimming pool, usually an artificial structure containing a large body of water intended for swimming * Reflecting pool, a shallow pool designed to reflect a structure and its surroundings * Tide pool, a rocky po ...
. This ExecutorService instance will be reused under the hood for revenant tasks, so it's possible runs as many concurrent tasks as the programmer wants throughout the life-cycle of the application using a single executor service instance. This is how the first thread-example looks like using executors: ExecutorService executor = Executors.newSingleThreadExecutor(); executor.submit(() -> ); The ExecutorService instance also supports a Callable interface, another single method interface like Runnable but the signature of the contained method of Callable returns a value. In this way, the lambda expression must also return a value. public static class SomeAsyncCode var webPageResult = SomeAsyncCode.getContentAsync().get(); Calling the method get() blocks the current thread and waits until the callable completes before returning the value (in the example, a web page content):


Additional features


Numeric applications

To adequately support applications in the field of mathematical and financial computation, several language features exist. Java's
strictfp strictfp is an obsolete and unused reserved word in the Java programming language. Previously, this keyword was used as a modifier that restricted floating-point calculations to IEEE 754 semantics in order to ensure portability. The strictfp keywor ...
keyword enables strict floating-point calculations for a region of code. Strict floating-point calculations require that even if a platform offers higher precision during calculations, intermediate results must be converted to single/double. This ensures that strict floating-point calculations return exactly the same result on all platforms. Without strict floating-point, a platform implementation is free to use higher precision for intermediate results during calculation. C# allows an implementation for a given hardware architecture to always use a higher precision for intermediate results if available, i.e. C# does not allow the programmer to optionally force intermediate results to use the potential lower precision of single/double. Although Java's floating-point arithmetic is largely based on IEEE 754 (Standard for Binary Floating-Point Arithmetic), certain features are unsupported even when using the strictfp modifier, such as Exception Flags and Directed Roundings, abilities mandated by IEEE Standard 754 (see Criticism of Java, Floating point arithmetic). C# provides a built-in decimal type, which has higher precision (but less range) than the Java/C# double. The decimal type is a 128-bit data type suitable for financial and monetary calculations. The decimal type can represent values ranging from 1.0 × 10−28 to approximately 7.9 × 1028 with 28–29 significant digits. The structure uses C# operator overloading so that decimals can be manipulated using operators such as +, -,*and /, like other primitive data types. The and types provided with Java allow arbitrary-precision representation of decimal numbers and integer numbers, respectively. Java standard library does not have classes to deal with complex numbers. The BigInteger, and Complex types provided with C# allow representation and manipulation of arbitrary-precision integers and complex numbers, respectively. The structures use C# operator overloading so that instances can be manipulated using operators such as +, -, *, and /, like other primitive data types. C# standard library does not have classes to deal with arbitrary-precision floating point numbers (see software for arbitrary-precision arithmetic). C# can help mathematical applications with the checked and unchecked operators that allow the enabling or disabling of run-time checking for
arithmetic overflow Arithmetic () is an elementary part of mathematics that consists of the study of the properties of the traditional operations on numbers—addition, subtraction, multiplication, division, exponentiation, and extraction of roots. In the 19th ce ...
for a region of code.


Language integrated query (LINQ)

C#s Language Integrated Query (LINQ) is a set of features designed to work together to allow in-language querying abilities and is a distinguishing feature between C# and Java. 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 an
abstract syntax tree In computer science, an abstract syntax tree (AST), or just syntax tree, is a tree representation of the abstract syntactic structure of text (often source code) written in a formal language. Each node of the tree denotes a construct occurr ...
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 clause 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 that may lead to a result type that cannot be named. * Query expressions to support a syntax familiar to SQL users. * Nullable (lifted) types to allow for a better match with query providers that support nullable types, like e.g. SQL.


Native interoperability

The
Java Native Interface In software design, the Java Native Interface (JNI) is a foreign function interface programming framework that enables Java code running in a Java virtual machine (JVM) to call and be called by native applications (programs specific to a hardwa ...
(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 (JNA) is a community-developed library that provides Java programs easy access to native shared libraries without using the Java Native Interface (JNI). JNA's design aims to provide native access in a natural way with a minim ...
(JNA) allows easier calling of native code that only requires writing Java code, but comes at a performance cost. In addition, third party
libraries A library is a collection of Document, materials, books or media that are accessible for use and not just for display purposes. A library provides physical (hard copies) or electronic media, digital access (soft copies) materials, and may be a ...
provide Java- Component Object Model (COM) bridging, e.g., JACOB ( free), and J-Integra for COM (
proprietary {{Short pages monitor