Comparison of C Sharp and Java explained

This article compares two programming languages: C# with Java. 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. For a more detailed comparison of the platforms, see Comparison of the Java and .NET platforms.

C# and Java are similar languages that are typed statically, strongly, and manifestly. Both are object-oriented, and designed with semi-interpretation or runtime just-in-time compilation, and both are curly brace languages, like C and C++.

Types

Data typesJava C#
[1] [2]
[3]
[4]
[5]
[6]
Date/time
reference type[7]
value type
reference type
scalar
High-precision decimal number
but see 'Arbitrary-size decimals' above
IEEE 754 binary32 floating point number
IEEE 754 binary64 floating point number
but wrapper types
[8] only method references[9]
[10]
8, 16, 32, 64 bits
Type annotations
but wrapper types
[11]
limited third-party available[12]
[13] [14]
but some method support[15]
8, 16, 32, 64 bits
only primitive types

Unified type system

Both languages are statically typed with class-based object orientation. 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 types all derive from a common root type. C# has a unified type system in which all types (besides unsafe pointers[16]) ultimately derive from a common root type. Consequently, all types implement the methods of this root type, and extension methods defined for the type apply to all types, even primitive 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 types, 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 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 (CLR) types. The C# type is exactly the same type as the 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 type is a reference type that wraps the primitive 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 in Java and a (signed byte) in C#.

Unsigned integers

C# supports unsigned in addition to the signed integer types. The unsigned types are,, and 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 (s) still yields a 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. Instead, Java's type is sign extended, which is a common source of bugs and confusion.[17]

Unsigned integers were left out of Java deliberately because James Gosling 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.[8] [18]

Java versions 8 and 9 added some limited built-in unsigned integer operations, but they are only exposed as static methods on the primitive wrapper classes; they operate on signed primitive integer types, treating them as if they were unsigned.[19]

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.[20] [21] Contrary to the and 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.[22]

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.

Advanced numeric types

Both languages offer library-defined arbitrary-precision arithmetic 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 numbers.

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 floating point types. For instance, none of the arbitrary-size types support square root or logarithms.

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 (character) datatype as a simple type. Although the type can be used with bit-wise operators, this is performed by promoting the 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 expressions are considered an external feature and are implemented in separate classes.

Both languages' libraries define classes for working with dates, times, time zones, and calendars in different cultures. Java provides, a mutable reference type with millisecond precision, and (since Java 8) the package (including classes such as,, and for date-only, time-only, and date-and-time values), a set of immutable reference types with nanosecond precision.[23] In contrast, the C# is an immutable struct value type for date-and-time information with 100-nanosecond precision; the .NET 6 API also added and, similar structures for date-only or time-only operations.[24] C# additionally defines a type for working with time periods; Java 8 provides the class for the same purpose. Both languages support date and time arithmetic according to different cultures and time zones.

User-defined value type (struct)

C# allows the programmer to create user-defined value types, using the 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 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 tables, 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 several interfaces.

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.[25] 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.

JavaC#
DefinitionIn Java, the enumeration type is a class, and its values are objects (instances) of that class. The only valid values are the ones listed in the enumeration. The enumeration type may declare fields, allowing each individual enumerated value to reference additional data associated uniquely with that specific value. The enumeration type may also declare or override methods, or implement interfaces.[26] Enumerations in C# are implicitly derived from the type that again is a value type derivative. The value set of a C# enumeration is defined by the underlying type that 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.[27] 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.
CombiningJava 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 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.[28] Fall-through must be explicitly declared using a goto statement.[29]

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, 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.[30] Instead, alternative mechanisms are used. The wrapper pattern, which resembles the delegates of C# in that it allows the client to access one or more client-defined methods through a known interface, is one such mechanism. Another is the use of adapter objects using inner classes, which the designers of Java argued are a better solution than bound method references.[30]

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 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 generic type, where 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 or it can be tested for . 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 value by virtue of being reference types (classes).

According to the Java spec, any attempt to dereference the reference must result in an exception being thrown at run-time, specifically a . (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 : 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 value of the operand; in Java, unboxing the null reference throws an exception.

Not all C# lifted operators have been defined to propagate unconditionally, if one of the operands is . Specifically, the boolean operators have been lifted to support ternary logic 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 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 type in C#:

Java does not support a late-bound type. The use cases for C# dynamic type have different corresponding constructs in Java:

See also example

  1. 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.[8] 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 (JNI) where communication with/adaptation to an underlying operating system is handled through an external glue layer.

While C# does allow use of pointers 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.[32] 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 keyword to be able to use pointers, and the compiler requires the switch to allow compiling such code. Assemblies that are compiled using the 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 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 references. They are much like weak references, but the Java virtual machine (JVM) will not deallocate softly-referenced objects until the memory is needed.

Reference types Java C#
Weak references
Reference queue (interaction with garbage collection)
Soft references
Phantom references
proxy generation
object contexts

Arrays and collections

Arrays and collections are concepts featured by both languages.

Java C#
Abstract data types
One-dimensional, zero-based index arrays
Multidimensional arrays, rectangular (single array)
Multidimensional arrays, jagged (arrays of arrays)
Non-zero based arrays
Unified arrays and collections
Sorted dictionaries [33]
Sets
Sorted sets [34]
Lists/vectors
[35]
Bags/multisets
Concurrency optimized collections [36]

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 . They are not unified with collection types.Arrays in C# are implicit specializations of the class that implements several collection interfaces.
Arrays and collections are completely separate with no unification. Arrays cannot be passed where sequences or collections are expected (though they can be wrapped using).Arrays can be passed where sequences (s) or collections/list interfaces are expected. However, the collection operations that alter the number of elements (insert/add/remove) will throw exceptions as these operations are unsupported by arrays.
The statement accepts either arrays or s. All collections implement . This means that the same short syntax can be used in for-loops.The statement iterates through a sequence using a specific implementation of the method, usually implemented through the or interface.[37] Because arrays always implicitly implement these interfaces, the loop will iterate through arrays also.
In both languages arrays of reference types are covariant. This means that a array is assignable to variables of, as is a specialization of (assignable to) . 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.
No multidimensional arrays (rectangular arrays), but arrays of references to arrays (jagged arrays).Multidimensional arrays (rectangular arrays), and arrays of references to arrays (jagged arrays).
Arrays cannot be resized (though use of the method can allow for multi-step array resizing)Arrays can be resized while preserving existing values using the static array method (but this may return a new array).
Implemented as a retrofit for the library having extra features, like data structures like sets and linked sets, and has several algorithms to manipulate elements of a collection, like finding the largest element based on some object, finding the smallest element, finding sublists within a list, reverse the contents of a list, shuffle the contents of a list, create immutable versions of a collection, performs sorts, and make binary searches.[38] The C# collections framework consists of classes from the and the namespaces with several useful interfaces, abstract classes, and data structures.[39] NET 3.5 added namespace that contains various extension methods for querying collections, such as,,,,, and many others. Queries using these methods are called Language Integrated Query (LINQ).

Multidimensional arrays can in some cases increase performance because of increased locality (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, 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.

Tuples

C# provides two different methods for creating tuple types (also known as product types). The first is via the classes, which are immutable reference types provided by the framework API (starting with .NET Framework 4.0) for creating generic tuple types.[13] This first method has since been effectively superseded by the second, the structs, which are mutable value types provided by the framework API (starting with .NET Framework 4.7).[14]

While the two methods seem superficially similar, they have multiple notable differences. The types are value types, so they have a more compact memory footprint; also, the types expose their contents as mutable fields, compared to the immutable properties of the classes. Finally, since C# version 7.0, the language has native syntactical support for the construction, deconstruction, and manipulation of tuples as instances; this also provides for the arbitrary renaming of the tuples' constituent fields (as opposed to, where the fields are always named,, etc.).

Java does not provide tuple types as part of its language or standard API; numerous third-party libraries exist which can provide tuple types,[40] but they all are necessarily similar to the C# classes. In comparison to C# types and their associated syntax, they are more unwieldy to use (requiring the explicit use of constructors or static factory methods for creating them, requiring individual member access to deconstruct them, and having fixed names for their elements).

Expressions and operators

Expressions and operators Java C#
Arithmetic operators
Logical operators
Bitwise logic operators
Conditional
String concatenation
Since Java 21 (details)
[41]
Verbatim (here-)strings [42] [43]
Casts
implicit
implicit
implicit
explicit
Lifted operators
See
Overflow control
Strict floating point evaluation
opt-in/out
opt-in[44]

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 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.[45]

This difference has the following consequences. First of all, in C#, primitive types can define methods, such as an override of Object's 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 a primitive value, as it will not be boxed automatically. The expression will convert an integer literal to string in Java while performs the same operation in C#. This is because the latter one is an instance call on the primitive value, while the former one is an instance call on an object of type .

Finally, another difference is that Java makes heavy use of boxed types in generics (see below).

Statements

Statements Java C#
Flow control
Exception control
Variable declaration
Variable type inference [46]
Deterministic disposal (ARM-blocks)

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 exist. 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 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 loop was extended to accept iterable types. An example of the latter can be found in how the and (especially) the keywords were reused for specifying type bounds when generics were introduced in Java 1.5. At one time (Java 1.4) a new keyword was introduced that was not reserved as a keyword before. This had the potential to render formerly valid code invalid, if for instance the code used 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 as a keyword when compiling as Java 1.4 and later, 3) Defaulting to 1.3 to avoid rendering prior (non 1.4 aware code) invalid and 4) Issue warnings, if the keyword is used in Java 1.3 mode, to allow changes in 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 and 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 prior version without specifying the language version to be used.

keyword feature, example usage
, In C#, statement blocks or expressions can enable run-time checking for arithmetic overflow.[47]
, C# implements properties as part of the language syntax with their optional corresponding and 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.
C# supports the [[goto]] keyword. This can be useful on occasion, for example for implementing finite state machines or for generated code, but use of a more structured method of control flow is usually recommended (see criticism of the goto statement). Java does not support the statement (but is a reserved word). However, Java does support labeled and statements, which in certain situations can be used when a statement might otherwise be used.

switch (color)

In C#, the keyword is a shorthand for synchronizing access to a block of code across threads (using a), wrapped in a ... block.
, C# has support for output and reference parameters. These allow returning multiple output values from a method, or passing values by reference.
Java uses [[strictfp]] to guarantee the results of floating point operations remain the same across platforms.
In C#, the switch statement also operates on strings and longs. Fallthrough is allowed for empty statements and possible via 'goto case' for statements containing code. Java's switch statement operates on strings (since Java 7) but not the primitive type, and falls through for all statements (excluding those with '').[48]
In Java, the keyword is a shorthand for synchronizing access to a block of code across threads (using a), wrapped in a ... block.
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.public int readItem throws java.io.IOException
In C#, causes the method (implemented via the interface) of the object declared to be executed after the code block has run or when an exception is thrown within the code block.// Create a small file "test.txt", write a string,// ... and close it (even if an exception occurs)using (var file = new StreamWriter("test.txt"))In Java SE 7 a similar construct has been added[49] called try-with-resources:try (BufferedReader br = new BufferedReader(new FileReader(path)))

Object-oriented programming

Both C# and Java are designed from the ground up as object-oriented languages using dynamic dispatch, with syntax similar to C++ (C++ in turn derives from C). Neither language is a superset of C or C++, however.

Object orientationJava C#
Member accessibility levels
Instance-level inner classes
Partial classes
Third-party library[50]
Implicit (inferred) anonymous classes
Not needed
[51]
Deprecation/obsolescence
Overload versioning
Indexers
Implicit conversions
but see autoboxing
Explicit conversions

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 . 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 (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, 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.[52] This is done via a new -operator introduced in JDK 1.3: . 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 . C# satisfies the use-cases for these by providing anonymous delegates; 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.

Event

C# multicast-delegates are used with events. Events provide support for event-driven programming and are 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.

Operator overloading and conversions

Operator overloading 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 and 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,,,,, and any variations of compound statements like . But compound operators will call overloaded simple operators, like calling and .[53]

Java does not include operator overloading, nor custom conversions to prevent abuse of the feature and to keep the language simple.[54]

Indexer

C# also includes indexers that can be considered a special case of operator overloading (like the C++), or parameterized / properties. An indexer is a property named that uses one or more parameters (indexes); the indices can be objects of any type:

myList[4] = 5;string name = xmlNode.Attributes["name"];orders = customerMap[theCustomer];

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

Fields and initialization Java C#
but no support for constant passed parameters[55]
Instance constructors
Instance initializers
can be simulated with instance constructor
Object initializers
Collection initializers
Array initializers

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:

  1. Derived static fields
  2. Derived static constructor
  3. Derived instance fields
  4. Base static fields
  5. Base static constructor
  6. Base instance fields
  7. Base instance constructor
  8. 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:

  1. Invocation of another constructor (either of the object's class or of the object's superclass)
  2. Instance variable initializers and instance initializers (in the order they appear in the source code)
  3. 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 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

Methods and properties Java C#
Static imports [56]
Virtual methods
Sealing
Explicit interface implementation [57]
Value (input) parameters
Reference (input/output) parameters
Output (output) parameters
Constant (immutable) parameters
final parameters
[58]
Optional arguments
[59] Instead method overloading or varargs
Named arguments
with annotations
Extension/default methods
Conditional methods
Partial 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 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.[60] [61] 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 implementations, 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.[62] 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. 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 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 is intended to override an inherited method, the 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 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 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, it is possible to prevent reassignment of a method parameter by using the keyword, however this keyword cannot be used on local variables. As with Java, applying 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.[63]

Both languages do not support essential feature of const-correctness that exists in C/C++, 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 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 or an immutable class, like a .

Generator methods

Any C# method declared as returning, or the generic versions of these interfaces can be implemented using 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.

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 .

See also example Fibonacci sequence below.

Explicit interface implementation

C# also has explicit interface implementation that allows a class to specifically implement methods of an interface, 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 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".[64]

width=50%Java !C#
class PassByRefTest class PassByRefTest

Exceptions

Exceptions Java C#
Checked exceptions
Try-catch-finally
Exception filters [65]

Checked exceptions

Java supports checked exceptions (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 clause.

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.[66] [67]

One criticism is that checked exceptions encourage programmers to use an empty catch block,[68] 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.[69] [70]

Try-catch-finally

There are also differences between the two languages in treating the statement. The block is always executed, even if the block contains control-passing statements like or . In Java, this may result in unexpected behavior, if the block is left by a statement with some value, and then the block that is executed afterward is also left by a statement with a different value. C# resolves this problem by prohibiting any control-passing statements like or in the block.

A common reason for using blocks is to guard resource managing code, thus guaranteeing the release of precious resources in the finally block. C# features the statement as a syntactic shorthand for this common scenario, in which the method of the object of the 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.

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: will just rethrow the original exception with the original stack, while would have created a new stack trace.

Finally blocks

Java allows flow of control to leave the block of a statement, regardless of the way it was entered. This can cause another control flow statement (such as) to be terminated mid-execution. For example:

int foo

In the above code, the statement within the block causes control to leave it, and thus block is executed before the actual return happens. However, the 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 block prematurely, except for . In particular, is not allowed at all, is not allowed if the target label is outside the block, and and are not allowed if the nearest enclosing loop is outside the block.

Generics

See also: Generic programming.

In the field of generics the two languages show a superficial syntactical similarity, but they have deep underlying differences.

Generics Java C#
Implementation
Runtime realization
Reference type constraint
implicit
Value/primitive type constraint
Constructor constraint
(only for parameterless constructor)
Subtype constraint
Migration compatibility

Type erasure versus reified generics

Generics in Java 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 Java virtual machine (JVM). Instead, generics classes and methods are transformed during compiling via a process termed type erasure. 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).

The Java 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.[71] 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:[72]

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,[73] but compared to compile-time verified code that would not need runtime casts and checks, these operations represent a performance overhead.C#/.NET generics guarantee type-safety and are verified at compile time, making extra checks/casts are unnecessary at runtime. Hence, generic code will run faster than non-generic (or type-erased) code that 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, as 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 that are realized with primitive/value type do not require boxing/unboxing conversions.
Generic exceptions are not allowed[74] and a type parameter cannot be used in a catch clause[75] Can both define generic exceptions and use those in catch clauses
Static members are shared across all generic realizations[76] (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 classesNo restrictions on use of type parameters
Cannot create an array where the component type is a generic realization (concrete parameterized type)Pair[] tenPairs = new Pair[10]; //OK

A generic realization is a 1st class citizen and can be used as any other class; also an array componentobject tenPairs = new Pair[10]; // OK
Cannot create an array where the component type is a type parameter, but it is valid to create an Object array and perform a typecast on the new array to achieve the same effect.public class Lookup

When a generic type parameter is under inheritance constraints the constraint type may be used instead of Objectpublic class Lookup>

Type parameters represent actual, discrete classes and can be used like any other type within the generic definition.public class Lookup
There is no class literal for a concrete realization of a generic typeA generic realization is an actual class.
is not allowed with type parameters or concrete generic realizationsThe and operators work the same for type parameters as for any other type.
Cannot create new instances using a type parameter as the typeWith a constructor constraint, generic methods or methods of generic classes can create instances of classes that have default constructors.
Type information is erased during compiling. 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 full reflection support and 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., instead of). 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 is allowed.[77] 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.[78]

Migration compatibility

Java's type erasure design was motivated by a design requirement to achieve migration compatibility – not to be confused with backward compatibility. 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".[45] This was designed so that any new generic collections should be passable to methods that expected one of the pre-existing collection classes.[79]

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

Java C#
Method references
[80]
Generic query language/API
Java Stream API (Monad)[81]
Tail recursion compiler optimizations [82] [83]

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.[84] [85]

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.

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 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

Java C#
Metadata annotations/attributes
user-defined annotations can be created[86]
Positional arguments
unless a single argument
Named arguments
Default values
Nested types
Specialization
Conditional metadata

Preprocessing, compilation and packaging

Java C#
File contents
Packaging
Classes/assembly search path [87] [88]
Conditional compilation
but see Apache Ant[89]
Custom errors/warnings
AnnotationProcessor
Explicit regions

Namespaces and file contents

In C#, namespaces 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., 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.,). C# allows importing classes under a new local name using the following syntax: . It also allows importing specializations of classes in the form of .

Both languages have 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 where 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 where can be an imported extension method working on the type of).

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 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 using preprocessor directives. It also provides a attribute 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, which is only evaluated when the 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 or switch when invoking the JVM.

Threading and asynchronous features

Both languages include thread synchronization mechanisms as part of their language syntax.

Java C#
Threads
Task-based parallelism [90] [91]
Thread-local variables
and class

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 and classes. Tasks can be composed and chained.

By convention, every method that returns a 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 methods and the 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 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 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. can execute asynchronous tasks and also manage a group of subprocesses. All the threads of an instance are handled in a pool. This 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 using executors:ExecutorService executor = Executors.newSingleThreadExecutor;

executor.submit(->);

The instance also supports a interface, another single method interface like but the signature of the contained method of returns a value. In this way, the lambda expression must also return a value, like the below example of calling a website asynchronously as the C# example.ExecutorService executor = Executors.newSingleThreadExecutor;

Future contentAsync = executor.submit(->); var webPageResult = contentAsync.get;Calling the method blocks the current thread and waits until the callable completes before returning the value (in the example, a web page content):

The following example, a method and a class are used. This wrap it's just to be similar to the C# example since Java does not have keywords like async for the method signature.public static class SomeAsyncCode

var webPageResult = SomeAsyncCode.getContentAsync.get;

Additional features

Numeric applications

To adequately support applications in the field of mathematical and financial computation, several language features exist.[92]

Java's strictfp 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.[93]

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,[94] 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.[95] 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,[3] and [96] 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 and operators that allow the enabling or disabling of run-time checking for arithmetic overflow 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 these features:

Native interoperability

Native interoperability Java C#
(with GraalVM, Nashorn, CORBA, JNI or JNA)
C# was designed for it[97]
External/native methods
metadata controlled
Pointers and arithmetics
but see sun.misc.Unsafe
Native types [98]
Fixed-size buffers
Explicit stack allocation
Address-of
Function pointers [99]
Unions [100]

The Java Native Interface (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 Java-Component Object Model (COM) bridging, e.g., JACOB (free), and J-Integra for COM (proprietary).

.NET Platform Invoke (P/Invoke) offers the same ability by allowing calls from C# to what Microsoft terms unmanaged code. Through metadata attributes the programmer can control exactly how the parameters and results are marshalled, thus avoiding the external glue code needed by the equivalent JNI in Java. 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 first-class .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 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 machine (JVM) and a common set of libraries. The JRE was originally designed to support interpreted execution with final compiling 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.

Examples

Input/output

Example illustrating how to copy text one line at a time from one file to another, using both languages.

JavaC#
valign=topimport java.nio.file.*;

class FileIOTest

valign=topusing System.IO;

class FileIOTest

valign=topNotes on the Java implementation:
  • method returns a List of String, with the content of the text file, Files has also the method, returns an array of .
  • method writes byte array or into an output file, indicated by a Path object.
  • method also takes care of buffering and closing the output stream.
valign=topNotes on the C# implementation:
  • The method returns an enumerable object that upon enumeration will read the file one line at a time.
  • The method takes an enumerable and retrieves a line at a time and writes it until the enumeration ends.
  • The underlying reader will automatically allocate a buffer, thus there is no need to explicitly introduce a buffered stream.
  • automatically closes the output stream, also in the case of an abnormal termination.

Integration of library-defined types

C# allows library-defined types to be integrated with existing types and operators by using custom implicit/explicit conversions and operator overloading as illustrated by the following example:

Interoperability with dynamic languages

This example illustrates how Java and C# can be used to create and invoke an instance of class that is implemented in another programming language. The "Deepthought" class is implemented using the Ruby programming language and represents a simple calculator that will multiply two input values (and) when the method is invoked. In addition to the conventional way, Java has GraalVM, a virtual machine capable to run any implemented programming language.

width=50%Javawidth=50%C#
valign=top

Using GraalVM

Context polyglot = Context.newBuilder.allowAllAccess(true).build;

//RubyValue rubyArray = polyglot.eval("ruby", "[1,2,42,4]");int rubyResult = rubyArray.getArrayElement(2).asInt;

//PythonValue pythonArray = polyglot.eval("python", "[1,2,42,4]");int pythonResult = pythonArray.getArrayElement(2).asInt;

//JavaScriptValue jsArray = polyglot.eval("js", "[1,2,42,4]");int jsResult = jsArray.getArrayElement(2).asInt;

//RValue rArray = polyglot.eval("R", "c(1,2,42,4)");int rResult = rArray.getArrayElement(2).asInt;

//LLVM (in this case C, but could be C++, Go, Basic, etc...)Source source = Source.newBuilder("llvm", new File("C_Program.bc")).build;Value cpart = polyglot.eval(source);cpart.getMember("main").execute;

Traditional way

// Initialize the enginevar invocable = new ScriptEngineManager.getEngineByName("jruby");var rubyFile = new FileReader("Deepthought.rb");engine.eval(fr);

// create a new instance of "Deepthought" calculatorvar calcClass = engine.eval("Deepthought");var calc = invocable.invokeMethod(calcClass, "new");

// set calculator input valuesinvocable.invokeMethod(calc, "a=", 6);invocable.invokeMethod(calc, "b=", 7);

// calculate the resultvar answer = invocable.invokeMethod(calc, "Calculate");

valign=top// Initialize the engine

var runtime = ScriptRuntime.CreateFromConfiguration;dynamic globals = runtime.Globals;

runtime.ExecuteFile("Deepthought.rb");

// create a new instance of "Deepthought" calculatorvar calc = globals.Deepthought.@new;

// set calculator input valuescalc.a = 6;calc.b = 7;

// calculate the resultvar answer = calc.Calculate;

Notes for the Java implementation:
  • Ruby accessors names are generated from the attribute name with a suffix. When assigning values, Java developers must use the Ruby accessor method name.
  • Dynamic objects from a foreign language are not first-class objects in that they must be manipulated through an API.
Notes for the C# implementation:
  • Objects returned from properties or methods of objects are themselves of type. When type inference (the keyword) is used, the variables calc and answer are inferred dynamic/late-bound.
  • Dynamic, late-bounds objects are first-class citizens that can be manipulated using C# syntax even though they have been created by an external language.
  • is a reserved word. The prefix allows keywords to be used as identifiers.

Fibonacci sequence

This example illustrates how the Fibonacci sequence can be implemented using the two languages. The C# version takes advantage of C# generator methods. The Java version takes the advantage of interface and method references. Both the Java and the C# examples use K&R style for code formatting of classes, methods and statements.

JavaC#
width=50%// The Fibonacci sequenceStream.generate(new Supplier).limit(10).forEach(System.out::println);width=50% valign=top// The Fibonacci sequencepublic IEnumerable Fibonacci
width=50%width=50% valign=top// print the 10 first Fibonacci numbersforeach (var it in Fibonacci.Take(10))
Notes for the Java version:
  • The Java 8 Stream interface is a sequence of elements supporting sequential and parallel aggregate operations.
  • The generate method returns an infinite sequential unordered stream where each element is generated by the provided Supplier.
  • The limit method returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.
  • The forEach method performs an action for each element of this stream, this action could be a lambda or a method reference.

Using a foreach

The same example above, but using a method returning an Iterable to maintain greater similarity with the C# example. Anything that implements the iterable interface can be iterated in a foreach.Iterable fibonacci(int limit) // print the 10 first Fibonacci numbersfor(int it: fibonacci(10))

The most common way to do the example above would be to use Streams, not Iterables. This could be returned from a method like the C# example, but it's unnecessary and could be used directly by just collecting the Stream.

Below is an example using Streams and the collecting the Stream calling in the foreach block.var fibonacci = Stream.generate(new Supplier);

// print the 10 first Fibonacci numbersfor(int it: fibonacci.limit(10).toList)

In addition to the toList collector in the foreach block, It's important to highlight that there are more collectors for every type of collection. Also, custom collectors could be created by implementing the interface or describing the implementation as a lambda expression, both cases passing it as arguments to the collect method of the object. In this example would be just calling the method instead if would have some complex type of object per item for the collection.

Both examples could also be done with and and avoid the generic in the interface implementation, but the generic is used to preserve greater similarity with the C# example.

Functional Style

The above algorithm can be written even more consistently, using . The iterate method receives a seed parameter, and a function that specifies what to do for each iteration. In this case, the seed can be a record class with the 2 initial values of the algorithm, and its respective transformation in each iteration. In short, the iterate method makes unnecessary the implementation of a Supplier.

record Pair(int a, int b) ;

Stream .iterate(new Pair(0, 1), p -> new Pair(p.b, p.a + p.b)) .limit(10) .map(p -> p.a) .forEach(System.out::println);

Notes for the C# version:
  • The method is defined as returning instances of the interface, which allows client code to repeatedly request the next number of a sequence.
  • The keyword converts the method into a generator method.
  • The statement returns the next number of the sequence and creates a continuation so that subsequent invocations of the interface's method will continue execution from the following statement with all local variables intact.
  • Tuple-assignment avoids the need to create and use a temporary variable when updating the values of the variables and .

See also

External links

Notes and References

  1. Web site: BigDecimal (Java 2 Platform SE 5.0) . Docs.oracle.com . 24 February 2015.
  2. Web site: Mpir.NET . 17 July 2015.
  3. Web site: BigInteger Struct (System.Numerics) . learn.microsoft.com . 14 April 2023.
  4. Web site: Collection (Java 2 Platform SE 5.0) . Docs.oracle.com . 20 May 2015.
  5. Web site: String (Java 2 Platform SE 5.0) . Docs.oracle.com . 20 May 2015.
  6. Web site: Math  - The Commons Math User Guide – Complex Numbers . 17 July 2015.
  7. Web site: Date (Java 2 Platform SE 5.0) . Docs.oracle.com . 20 May 2015.
  8. Web site: The Java Language Environment . Oracle.com . 18 August 2013.
  9. Web site: Method References (The Java Tutorials > Learning the Java Language > Classes and Objects) . Docs.oracle.com . 28 February 2012 . 24 February 2015.
  10. Only available in unsafe mode or through IntPtr managed type
  11. The type system is unified by default, unless the compiler is switched into unsafe mode where raw pointers are available as a datatype. Pointers are not derived from object nor does it have implicit conversions to/from the object data type
  12. Web site: org.apache.commons.lang3.tuple (Apache Commons Lang 3.4-SNAPSHOT API) . Commons.apache.org . 15 January 2014 . 24 February 2015.
  13. Web site: Tuple Class (System) . learn.microsoft.com . Microsoft Corporation . 20 April 2023.
  14. Web site: Tuple types (C# reference) . learn.microsoft.com . Microsoft Corporation . 20 April 2023.
  15. Web site: Unsigned Integer Arithmetic API now in JDK 8 (Joseph D. Darcy's Oracle Weblog) . Blogs.oracle.com . 24 February 2015 . 25 February 2017 . https://web.archive.org/web/20170225213350/https://blogs.oracle.com/darcy/entry/unsigned_api . dead.
  16. Web site: Unsafe code, pointer types, and function pointers . learn.microsoft.com . 29 May 2022 . 14 April 2023.
  17. Book: Java puzzlers : traps, pitfalls, and corner cases. 2005 . Addison-Wesley. Upper Saddle River, NJ [u.a.]. 978-0-321-33678-1. Joshua Bloch; Neal Gafter. 5. print.. 36. The lesson for language designers is that sign extension of byte values is a common source of bugs and confusion. The masking that is required to suppress sign extension clutters programs, making them less readable. Therefore, the byte type should be unsigned..
  18. Web site: James Gosling on Java, May 2001 . Artima.com . 10 May 2001 . 24 February 2015.
  19. Web site: Integer (Java Platform SE 8) . Docs.oracle.com . 20 Apr 2023.
  20. Web site: decimal . C# Reference . 19 August 2012 . Microsoft.
  21. Book: Mok, Heng Ngee . From Java to C? : a developer's guide . 2003 . Addison-Wesley. Harlow, England . 978-0-321-13622-0 . 9.5. The decimal type.
  22. Book: Sestoft, Jon Jagger, Nigel Perry, Peter . C? annotated standard . 2007 . Elsevier/Morgan Kaufmann Publishers . Amsterdam . 978-0-12-372511-0 . 11.1.7 The decimal type.
  23. Web site: Package java.time (Java Platform SE 8) . docs.oracle.com . 20 April 2023.
  24. Web site: How to use the DateOnly and TimeOnly structures . 12 January 2023 . learn.microsoft.com . 20 April 2023.
  25. Web site: Enum. . .NET Perls . Internet . en . 14 November 2016 . Performance. Enums are fast. They are almost never a performance concern. They are just syntactic sugar on a type like int, which is also fast. […] Type. An enum has an underlying type. Each time we use the enum, we are using the underlying type. The enum has syntactic sugar on top..
  26. Web site: A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language . Dare Obasanjo . 2007 . Dare Obasanjo . In Java, enumerated types are a full-fledged class that means they are typesafe and can be extended by adding methods, fields or even implementing interfaces. Whereas in C#, an enumerated type is simply syntactic sugar around an integral type (typically an int) meaning they cannot be extended and are not typesafe. . 6 September 2012 . live . dmy-all . https://web.archive.org/web/20011217071122/http://www.25hoursaday.com:80/CsharpVsJava.html . 17 December 2001.
  27. Web site: Java 5: Taming the Tiger: Syntactic Sugar . Prof. Dr. Gruntz . Dominik . 8 April 2005 . de . Fachhochschule Aargau, Nordwestschweiz . https://web.archive.org/web/20120708065042/http://cstruter.com/ . 8 July 2012 . Enumerationen sind die heimlichen Sieger von Java 1.5. Nach vielen Beteuerungen durch Sun, Enums seien in Java überflüssig und können einfach nachgebildet werden, wurden sie nun doch eingeführt. Die einfachste Möglichkeit einer Enumeration der Jahreszeiten sieht wie folgt aus … Das Schlüsselwort enum steht für eine spezielle Art von Klasse, die eine Enumeration definiert. … Im Gegensatz zu anderen Programmiersprachen wie C/C++ und C# kann man ihnen per Gleichheitszeichen keine ganzen Zahlen zuordnen. . 10 September 2012 . dead . dmy-all.
  28. Web site: A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: C. An Ever So Slight Feeling of Dèjà Vu: 4. Switch Statement . Dare Obasanjo . 2007 . Dare Obasanjo . https://web.archive.org/web/20120919093308/http://25hoursaday.com/ . 19 September 2012 . 10 September 2012 . dead . dmy-all.
  29. Web site: goto (C#) . Msdn.microsoft.com . 18 August 2013.
  30. Web site: Oracle Technology Network for Java Developers | Oracle Technology Network | Oracle . Java.sun.com . 24 February 2015 . dead . https://web.archive.org/web/20120627043929/http://java.sun.com/docs/white/delegates.html . 27 June 2012 .
  31. http://blogs.sun.com/javafx/entry/how_to_use_javafx_in How to Use JavaFX in Your Swing Application
  32. Web site: Unsafe Code and Pointers (C# Programming Guide) . Microsoft . 11 March 2013.
  33. Web site: SortedDictionary Class (System.Collections.Generic) . learn.microsoft.com . 20 April 2023.
  34. Web site: SortedSet Class (System.Collections.Generic) . learn.microsoft.com . 20 April 2023.
  35. Web site: PriorityQueue Class (System.Collections.Generic) . learn.microsoft.com . 20 April 2023.
  36. Web site: System.Collections.Concurrent Namespace . learn.microsoft.com . 20 April 2023.
  37. Web site: foreach, in (C# reference) . 2018 . Microsoft . https://web.archive.org/web/20190112220056/https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/foreach-in . 12 January 2019 . The foreach statement executes a statement or a block of statements for each element in an instance of the type that implements the or interface. . 26 January 2019 . live.
  38. Web site: A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: C. An Ever So Slight Feeling of Dèjà Vu: 6. Collections . Dare Obasanjo . 2007 . Dare Obasanjo . https://web.archive.org/web/20120919093308/http://25hoursaday.com/ . 19 September 2012 . The Java collections framework not only has methods that enable one to access unsafe collections in a thread safe manner, but contains thread-safe versions of most of the data structures as well. The Java collections framework has a number of algorithms for manipulating the elements within the data structures including algorithms that can do the following; find the largest element based on some Comparator, find the smallest element, find sublists within a list, reverse the contents of a list, shuffle the contents of a list, creates immutable versions of a collection, performs sorts, and binary searches. . 10 September 2012 . dead . dmy-all.
  39. Web site: A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: C. An Ever So Slight Feeling of Dèjà Vu: 6. Collections . Dare Obasanjo . Dare Obasanjo . https://archive.today/20130102015335/http://www.25hoursaday.com/CsharpVsJava.html . 2 January 2013 . March 2007 . The C# collections framework consists of the classes in the System. Collections and the System.Collections.Generic namespaces. The namespace contains interfaces and abstract classes that represent abstract data types such as, and that enable developers to manipulate data structures independently of how they are actually implemented as long as the data structures inherit from the abstract data types. The System.Collections namespace also contains some concrete implementations of data structures such as and . All four of the concrete data structure implementations enable one to obtain synchronized wrappers to the collection that allows for access in a thread-safe manner. The namespace has generic implementations of the key data structures in the System.Collections namespace including generic,,, and classes. . 10 September 2012 . dead .
  40. Web site: javatuples . 20 April 2023.
  41. Web site: String interpolation using $ . 8 April 2023 . learn.microsoft.com . 20 April 2023.
  42. Web site: JEP 378: Text Blocks . 5 August 2020.
  43. Web site: A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: D. Now for Something Completely Different: 13. Verbatim Strings . Dare Obasanjo . 2007 . Dare Obasanjo . https://web.archive.org/web/20120919093308/http://25hoursaday.com/ . 19 September 2012 . 11 September 2012 . dead . dmy-all.
  44. Web site: Microsoft Visual C++ Floating-Point Optimization . Eric Fleegal . 2004 . MSDN . 1 January 2016.
  45. Web site: The Java Community Process(SM) Program – JSRs: Java Specification Requests – detail JSR# 14 . Jcp.org . 24 February 2015.
  46. Web site: JEP 286: Local-Variable Type Inference . 25 April 2018.
  47. Web site: A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: D. Now for Something Completely Different: 14. Overflow Detection . Dare Obasanjo . 2007 . https://web.archive.org/web/20120922081727/http://www.25hoursaday.com/CsharpVsJava.html . 22 September 2012 . 11 September 2012 . dmy-all.
  48. Web site: A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: An Ever So Slight Feeling of Dèjà Vu: 4. . Dare Obasanjo . 2007 . https://web.archive.org/web/20120922081727/http://www.25hoursaday.com/CsharpVsJava.html . 22 September 2012 . 7 September 2012 . dmy-all.
  49. Web site: The try-with-resources Statement (The Java Tutorials > Essential Classes > Exceptions) . Docs.oracle.com . 28 February 2012 . 24 February 2015.
  50. [AspectJ|Extension created for the Java programming language]
  51. Web site: Anonymous Types (C# Fundamentals) . learn.microsoft.com . 14 April 2013.
  52. Web site: Java SE Specifications . Java.sun.com . 24 February 2015.
  53. Web site: A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: Operator Overloading . Dare Obasanjo . 2007 . Dare Obasanjo . https://web.archive.org/web/20120919093308/http://25hoursaday.com/ . 19 September 2012 . Note: Unlike C++, C# does not allow the overloading of the following operators;, or any variations of compound assignments such as, etc. However, compound assignment operators will call overloaded operators, for instance, would call overloaded . . 6 September 2012 . dead . dmy-all.
  54. Web site: Java News from August, 1998 . Cafeaulait.org . 24 February 2015.
  55. Web site: C# Equivalent to Java's "final" . Sunwold . Corey . 25 February 2010 . Corey Sunwold . https://archive.today/20121129011204/http://csunwold.blogspot.co.at/2010/02/from-stackoverflow-im-looking-for-c.html . live . 29 November 2012 . There is than one use of the final keyword that C# does not have an equivalent for. When you pass a parameter to a method in Java, and you don't want that parameter's value to change within the scope of that method you can set it as final like this: . 13 September 2016 .
  56. Web site: C# – A C# 6.0 Language Preview . July 2015 . learn.microsoft.com . 14 April 2023.
  57. Web site: A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: D. Now for Something Completely Different: 15. Explicit Interface Implementation . Dare Obasanjo . 2007 . Dare Obasanjo . https://web.archive.org/web/20120922081727/http://www.25hoursaday.com/CsharpVsJava.html#explicitinterface . 22 September 2012 . 11 September 2012 . live . dmy-all.
  58. Web site: in parameter modifier (C# Reference) . 5 March 2018 . Microsoft . https://archive.today/20190126124708/https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier . live . 26 January 2019 . 26 January 2019.
  59. Web site: Gosling. James . The Java® Language Specification . 5 October 2014. Section 8.4.1. Formal Parameters.
  60. Web site: How do Extension Methods work and why was a new CLR not required?. Scott. Hanselman. 4 April 2008. Extension methods are a really nice syntactic sugar. They're not really added to the class, as we can see, but the compiler makes it feel like they are. 29 March 2014.
  61. Web site: Extension Methods (C# Programming Guide). Microsoft. 2013. Extension methods are defined as static methods but are called by using instance method syntax. 29 March 2014.
  62. Web site: C# Language Specification Version 4.0 . Microsoft . 10 May 2012 . 281 . If no part of a partial type declaration contains an implementing declaration for a given partial method, any expression statement invoking it is simply removed from the combined type declaration. Thus the invocation expression, including any constituent expressions, has no effect at run-time. The partial method itself is also removed and will not be a member of the combined type declaration. If an implementing declaration exist for a given partial method, the invocations of the partial methods are retained. The partial method gives rise to a method declaration similar to the implementing partial method declaration except for the following: […].
  63. Web site: in parameter modifier (C# Reference) . 5 March 2018 . Microsoft . https://archive.today/20190126124708/https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier . live . 26 January 2019 . The in keyword causes arguments to be passed by reference. It is like the ref or out keywords, except that in arguments cannot be modified by the called method. . 26 January 2019.
  64. Web site: A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: D. Now for Something Completely Different: 12. Pass by Reference . Dare Obasanjo . 2007 . Dare Obasanjo . https://web.archive.org/web/20120919093308/http://25hoursaday.com/ . 19 September 2012 . In Java the arguments to a method are passed by value meaning that a method operates on copies of the items passed to it instead of on the actual items. In C#, as in C++ and in a sense C, it is possible to specify that the arguments to a method actually be references to the items being passed to the method instead of copies. This feature 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 and leads to anomalies like: a method that swaps two numbers that have been the hallmark of freshman computer science classes for years, is impossible to do in Java without resorting to coding tricks. . 10 September 2012 . dead . dmy-all.
  65. Web site: Exceptional Exception Filtering . Pluralsight® . 24 June 2022.
  66. Web site: The Trouble with Checked Exceptions . Artima.com . 24 February 2015.
  67. Web site: Msdn forums – Visual C# Language . Msdn2.microsoft.com . 24 February 2015 . https://web.archive.org/web/20070320060200/http://msdn2.microsoft.com/en-us/vcsharp/aa336812.aspx . 20 March 2007 . dead.
  68. Web site: Eckel . Bruce . Does Java need Checked Exceptions? . 6 December 2012 . https://web.archive.org/web/20020405175011/http://www.mindview.net/Etc/Discussions/CheckedExceptions . 5 April 2002 . dead .
  69. Web site: Failure and Exceptions . Artima.com . 22 September 2003 . 18 August 2013.
  70. Web site: Checked Exceptions . Shaun Abram . 18 August 2013.
  71. Web site: Java SE Specifications . Java.sun.com . 24 February 2015.
  72. Web site: Angelika Langer . Java Generics FAQs – Frequently Asked Questions – Angelika Langer Training/Consulting . AngelikaLanger.com . 24 February 2015.
  73. Web site: Angelika Langer . Java Generics FAQs – Under The Hood of the Compiler – Angelika Langer Training/Consulting . AngelikaLanger.com . 16 April 2013 . 18 August 2013.
  74. Web site: Angelika Langer . Java Generics FAQs – Under The Hood of the Compiler – Angelika Langer Training/Consulting . AngelikaLanger.com . 16 April 2013 . 18 August 2013.
  75. Web site: Angelika Langer . Java Generics FAQs – Under The Hood of the Compiler – Angelika Langer Training/Consulting . AngelikaLanger.com . 16 April 2013 . 18 August 2013.
  76. Web site: Angelika Langer . Java Generics FAQs – Type Parameters – Angelika Langer Training/Consulting . AngelikaLanger.com . 13 February 2014 . 24 February 2015.
  77. Web site: Generics in C#, Java, and C . Artima.com . 24 February 2015.
  78. Web site: trove4j / Trove . 30 June 2017.
  79. Web site: Neal Gafter . Neal Gafter's blog: Puzzling Through Erasure: answer section . Gafter.blogspot.com . 23 September 2004 . 18 August 2013.
  80. Web site: Lambda Expressions (The Java Tutorials > Learning the Java Language > Classes and Objects) . Docs.oracle.com . 28 February 2012 . 24 February 2015.
  81. Web site: Lesson: Aggregate Operations (The Java Tutorials > Collections) . Docs.oracle.com . 28 February 2012 . 24 February 2015.
  82. Web site: Curly Braces #6: Recursion and tail-call optimization . 2022-11-07 . 2024-07-17 . Bruno . Eric . https://web.archive.org/web/20240717183057/https://blogs.oracle.com/javamagazine/post/curly-braces-java-recursion-tail-call-optimization . 2024-07-17 . live.
  83. Web site: Tail Call Improvements in .NET Framework 4 . Grant Richins . . 11 May 2009.
  84. Web site: An Introduction to Delegates . MSDN Magazine . April 2001 . 23 December 2008 . Richter . Jeffrey . Jeffrey Richter.
  85. Web site: What's in a Closure? . Did it with .NET . Campbell . Dustin . 9 February 2007 . 23 December 2008 . https://web.archive.org/web/20140815085318/http://diditwith.net/PermaLink,guid,235646ae-3476-4893-899d-105e4d48c25b.aspx . 15 August 2014 . dead . dmy-all.
  86. Web site: A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: Metadata Annotations . Dare Obasanjo . 2007 . Dare Obasanjo . https://web.archive.org/web/20120919093308/http://25hoursaday.com/ . 19 September 2012 . However a key difference between C# attributes and Java annotations is that one can create meta-annotations (i.e., annotations on annotations) in Java but can not do the same in C#. Developers can create their own custom annotations by creating an annotation type that is similar to an interface except that the keyword @interface is used to define it. . 6 September 2012 . dead . dmy-all.
  87. Web site: Element . Msdn.microsoft.com . 18 August 2013.
  88. Web site: C# Assembly – Custom Reference Path – Visual C# Kicks . Vcskicks.com . 18 August 2013.
  89. Web site: How to do Conditional Compilation with Java . weblogs.java.net . 11 August 2015 . https://web.archive.org/web/20130105043626/http://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html . 5 January 2013 . dead . dmy-all.
  90. Fork-join framework included with Java version 7. Web site: ForkJoinPool (Java Platform SE 7) . Oracle . 17 July 2015.
  91. Web site: Task Parallel Library (TPL) . Msdn.microsoft.com . 18 February 2015 . 24 February 2015.
  92. Web site: Java for Scientific Computation : Prospects and Problems . Pds.ewi.tudelft.nl . 24 February 2015 . https://web.archive.org/web/20070922004052/http://www.pds.ewi.tudelft.nl/pubs/papers/scicomp01.pdf . 22 September 2007 . dead . dmy-all.
  93. Web site: C# Language Specification Version 5.0 . Floating-point operations may be performed with higher precision than the result type of the operation. For example, some hardware architectures support an "extended" or "long double" floating-point type with greater range and precision than the double type, and implicitly perform all floating-point operations using this higher precision type. Only at excessive cost in performance can such hardware architectures be made to perform floating-point operations with less precision, and rather than require an implementation to forfeit both performance and precision, C# allows a higher precision type to be used for all floating-point operations. Other than delivering more precise results, this rarely has any measurable effects. However, in expressions of the form x*y/z, where the multiplication produces a result that is outside the double range, but the subsequent division brings the temporary result back into the double range, the fact that the expression is evaluated in a higher range format may cause a finite result to be produced instead of an infinity. . Microsoft . 28 October 2013 . 4.1.6 Floating point types.
  94. Web site: decimal vs. 110 . 24 February 2015.
  95. Web site: C# Language Specification Version 5.0 . Microsoft . 4.1.7 The decimal type.
  96. Web site: Complex . 24 February 2015.
  97. Web site: A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: C. An Ever So Slight Feeling of Dèjà Vu: 15. Cross Language Interoperability . Dare Obasanjo . 2007 . Dare Obasanjo . https://web.archive.org/web/20120919093308/http://25hoursaday.com/ . 19 September 2012 . There are a number of ways cross language interoperability works in Java. First of all, there is the Java Native Interface (JNI) … Java also has the ability to interact with distributed objects that use the common object request broker architecture (CORBA) via Java IDL. … C# and the .NET runtime were created with seamless cross-language interoperability as a design goal. . 10 September 2012 . dead . dmy-all.
  98. Web site: JNI Types and Data Structures . Docs.oracle.com . 9 April 2020.
  99. Web site: Function pointers in C# 9 . docs.microsoft.com . 27 February 2021.
  100. Web site: Creating C/C++ unions in C# . docs.microsoft.com . 27 February 2021.