Comparison table of C# and Java
Native interoperability
Native interoperability Java C#
Cross-language interoperability Yes Yes
External/native methods Yes Yes
Marshalling External glue code required Yes metadata controlled
Pointers and arithmetics***** No Yes
Native types Yes Yes
Fixed-size buffers No Yes
Explicit stack allocation No Yes
Address-of No Yes
Object pinning (fix variable to address) No Yes
Metadata
Metadata Java C#
Metadata annotations/attributes Interface based; user-defined annotations can be created Class based
Positional arguments No; unless a single argument Yes
Named arguments Yes Yes
Default values At definition Through initialization
Nested types Yes Yes
Specialization No Yes
Conditional metadata No Yes
Class access specifiers Only One public class in file to compile Multiple public classes allowed in same file to compile.
#region keyword* Yes No
Native code calls** Yes; with JNI Yes; using plaform Invoke
Conditional compilation*** Yes using preprocessor directives No
Runtime Enviroment**** Yes; JRE Yes; CLR
Extensions Yes Yes
Single-Line comments(//) Yes Yes
Double-Line comments(/*...*/) Yes Yes
Platform support
Platform support Java C#
Linux Yes via Mono
Mac OS X Yes via Mono
Solaris Yes via Mono
FreeBSD Yes via Mono
AIX Yes Partial?
iOS via RoboVM or Codename One via Mono
Windows Yes Yes
Windows Mobile Yes Yes
Windows Phone via Codename One Yes
Windows 8 Modern Yes Yes
Android via Dalvik, ART via Mono
Feature phones Yes No
Symbian Yes Deprecated
Blackberry Yes via cross-compiler
*#region Keyword - The #region keyword is used to segment a source code into blocks
#region Main method of code
public void Main(String[] args)
{
Console.WriteLine("ClashAPp!");
}
end #region
**Native calls and unmanaged codes -
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 for Java-COM bridging, e.g. JACOB (free), and J-Integra for COM (proprietary).
.NET Platform Invoke (P/Invoke) offers the same capability by allowing calls from C# to what Microsoft refers to as unmanaged code. Through metadata attributes the programmer can control exactly how the parameters and results are marshalled, thus avoiding the need for extra adaption code. P/Invoke allows almost complete access to procedural APIs (such as Win32 or POSIX), but limited access to C++ class libraries.
***Conditional compilation
Unlike Java, C# implements conditional compilation using preprocessor directives. It also provides a Conditional 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 Debug.Assert(), which is only evaluated when the DEBUG constant is defined. Since version 1.4, Java provides a language feature for assertions, which are turned off at runtime by default but can be enabled using the -enableassertions or -ea switch when invoking the JVM.
****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) as well as a common set of libraries. The JRE was originally designed to support interpreted execution with final compilation as an option. Most JRE environments execute fully or at least partially compiled programs, possibly with adaptive optimization. The Java compiler produces Java bytecode. Upon execution the bytecode is loaded by the Java runtime and either interpreted directly or compiled to machine instructions and then executed.
C# is designed to execute on the Common Language Runtime (CLR). The CLR is designed to execute fully compiled code. The C# compiler produces Common Intermediate Language instructions. Upon execution the runtime loads this code and compiles to machine instructions on the target architecture.
*****Extensions
The Java extension mechanism enables developers to extend the abilities of the core Java platform. Developers can create classes and packages which are treated by the Java runtime as if they are core Java classes and packages like java.lang, java.util, java.net,etc. This means that extensions do not have to be placed on the class path since they are treated as if they are part of the core libraries such as those in the Java runtime library, rt.jar. Extensions are contained within JAR files and once installed are available to all applications running on the target platform.
A C# parallel would be the ability to create assemblies that are treated as if they are part of the System namespace contained in the System.dll assembly.
Metadata
C# provides attributes to add annotations (i.e. metadata) to a type, method, parameter, module or member variable to extend C# capabilities. Below is a code snippet of an attribute that is intrinsic to the .NET framework and how it is used.
[Flags]
enum CodePlay{
Clash = 1,
App = 2,
All = Clash | App
}
Java annotations provide a way to add annotations (i.e. metadata) to a package, type, method, parameter, member or local variable. There are only three built-in annotations provided in the Java language which are @Documented, @Retention and @interface .
As in C# it is possible to access the annotations on a module, class, method or field via reflection. 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 which is similar to an interface except that the keyword @interface is used to define it. What follows is an example of using an attribute to provide information about the author of a class then using reflection to access that information.
@Retention(RetentionPolicy.RUNTIME)
@interface AnnotationInfo{
String annotation();
String name();
String version() default "1.0";
}
@AuthorInfo(annotation="ClashApp", name="ClashApp@yahoo.com")
class HelloWorld{
}
public class Test{
public static void main(String[] args) throws Exception{
Class cl = Class.forName("HelloWorld");
AnnotationInfo ann = (AnnotationInfo) c.getAnnotation(AnnotationInfo.class);
System.out.println("Annotation Information for " + cl);
System.out.println("annotation: " + ann.annotation());
System.out.println("name: " + ann.name());
System.out.println("Version: " + ann.version());
}
}
In the code snippet above, the @Documented annotation indicates it is to show up in the javadocs and the @Retention annotation indicates metadata to be exposed at runtime.
*****Pointers
Java does not permit pointers or pointer-arithmetic within the Java runtime environment. The Java language designers reasoned that pointers were one of the primary features that enable programmers to inject bugs into their code and chose not to support them. Java does not allow for directly passing and receiving objects/structures to/from the underlying operating system and thus does not need to model objects/structures to such a specific memory layout, layouts which frequently would involve pointers. Java's communication with the underlying operating system is instead based upon JNI where communication with/adaption 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 does not permit pointers. However, because pointers are required when calling many native functions, pointers are actually allowed in an explicit "unsafe" mode. Code blocks or methods that use the pointers must be marked with the unsafe keyword to be able to use pointers, and the compiler requires the /unsafe switch to allow compilation of such code. Assemblies which are compiled using the /unsafe switch are marked as such and may only execute if explicitly trusted. This allows programmers to use 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 at the same time isolate such potentially unsafe code in specifically trusted assemblies.
To write unsafe code, the unsafe keyword must be used to specify the code block as unsafe and the program must be compiled with the /unsafe compiler switch.
Since garbage collection may relocate managed (i.e. safe) variables during the execution of a program, the fixed keyword is provided so that the address of a managed variable is pinned during the execution of the parts of the program within the fixed block. Without the fixed keyword there would be little purpose in being able to assign a pointer to the address of a managed variable since the runtime may move the variable from that address as part of the mark & compact garbage collection process.
C# Code
using System;
class UnsafeCode{
public static unsafe void Swap(int* numOne, int*numTwo){
int temp = *numOne;
*numOne = *numTwo;
*numTwo = temp;
}
public static unsafe void Sort(int* array, int size){
for(int i= 0; i < size - 1; i++)
for(int j = i + 1; j < size; j++)
if(array[i] > array[j])
Swap(&array[i], &array[j]);
}
public static unsafe void Main(string[] args){
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Console.WriteLine("Unsorted Array:");
foreach(int x in array)
Console.Write(x + " ");
fixed( int* iptr = array ){
Sort(iptr, array.Length);
}
Console.WriteLine("\nSorted Array:");
foreach(int x in array)
Console.Write(x + " ");
}
}
In the code snippet above, the unsafe Sort method is indicated by the unsafe keyword while pinning the address of the managed array variable during the execution of the parts of the program the fixed keyword is used.
Native interoperability Java C#
Cross-language interoperability Yes Yes
External/native methods Yes Yes
Marshalling External glue code required Yes metadata controlled
Pointers and arithmetics***** No Yes
Native types Yes Yes
Fixed-size buffers No Yes
Explicit stack allocation No Yes
Address-of No Yes
Object pinning (fix variable to address) No Yes
Metadata
Metadata Java C#
Metadata annotations/attributes Interface based; user-defined annotations can be created Class based
Positional arguments No; unless a single argument Yes
Named arguments Yes Yes
Default values At definition Through initialization
Nested types Yes Yes
Specialization No Yes
Conditional metadata No Yes
Class access specifiers Only One public class in file to compile Multiple public classes allowed in same file to compile.
#region keyword* Yes No
Native code calls** Yes; with JNI Yes; using plaform Invoke
Conditional compilation*** Yes using preprocessor directives No
Runtime Enviroment**** Yes; JRE Yes; CLR
Extensions Yes Yes
Single-Line comments(//) Yes Yes
Double-Line comments(/*...*/) Yes Yes
Platform support
Platform support Java C#
Linux Yes via Mono
Mac OS X Yes via Mono
Solaris Yes via Mono
FreeBSD Yes via Mono
AIX Yes Partial?
iOS via RoboVM or Codename One via Mono
Windows Yes Yes
Windows Mobile Yes Yes
Windows Phone via Codename One Yes
Windows 8 Modern Yes Yes
Android via Dalvik, ART via Mono
Feature phones Yes No
Symbian Yes Deprecated
Blackberry Yes via cross-compiler
*#region Keyword - The #region keyword is used to segment a source code into blocks
#region Main method of code
public void Main(String[] args)
{
Console.WriteLine("ClashAPp!");
}
end #region
**Native calls and unmanaged codes -
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 for Java-COM bridging, e.g. JACOB (free), and J-Integra for COM (proprietary).
.NET Platform Invoke (P/Invoke) offers the same capability by allowing calls from C# to what Microsoft refers to as unmanaged code. Through metadata attributes the programmer can control exactly how the parameters and results are marshalled, thus avoiding the need for extra adaption code. P/Invoke allows almost complete access to procedural APIs (such as Win32 or POSIX), but limited access to C++ class libraries.
***Conditional compilation
Unlike Java, C# implements conditional compilation using preprocessor directives. It also provides a Conditional 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 Debug.Assert(), which is only evaluated when the DEBUG constant is defined. Since version 1.4, Java provides a language feature for assertions, which are turned off at runtime by default but can be enabled using the -enableassertions or -ea switch when invoking the JVM.
****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) as well as a common set of libraries. The JRE was originally designed to support interpreted execution with final compilation as an option. Most JRE environments execute fully or at least partially compiled programs, possibly with adaptive optimization. The Java compiler produces Java bytecode. Upon execution the bytecode is loaded by the Java runtime and either interpreted directly or compiled to machine instructions and then executed.
C# is designed to execute on the Common Language Runtime (CLR). The CLR is designed to execute fully compiled code. The C# compiler produces Common Intermediate Language instructions. Upon execution the runtime loads this code and compiles to machine instructions on the target architecture.
*****Extensions
The Java extension mechanism enables developers to extend the abilities of the core Java platform. Developers can create classes and packages which are treated by the Java runtime as if they are core Java classes and packages like java.lang, java.util, java.net,etc. This means that extensions do not have to be placed on the class path since they are treated as if they are part of the core libraries such as those in the Java runtime library, rt.jar. Extensions are contained within JAR files and once installed are available to all applications running on the target platform.
A C# parallel would be the ability to create assemblies that are treated as if they are part of the System namespace contained in the System.dll assembly.
Metadata
C# provides attributes to add annotations (i.e. metadata) to a type, method, parameter, module or member variable to extend C# capabilities. Below is a code snippet of an attribute that is intrinsic to the .NET framework and how it is used.
[Flags]
enum CodePlay{
Clash = 1,
App = 2,
All = Clash | App
}
Java annotations provide a way to add annotations (i.e. metadata) to a package, type, method, parameter, member or local variable. There are only three built-in annotations provided in the Java language which are @Documented, @Retention and @interface .
As in C# it is possible to access the annotations on a module, class, method or field via reflection. 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 which is similar to an interface except that the keyword @interface is used to define it. What follows is an example of using an attribute to provide information about the author of a class then using reflection to access that information.
Java Code
import java.lang.annotation.*;
import java.lang.reflect.*;
@Documented import java.lang.annotation.*;
import java.lang.reflect.*;
@Retention(RetentionPolicy.RUNTIME)
@interface AnnotationInfo{
String annotation();
String name();
String version() default "1.0";
}
@AuthorInfo(annotation="ClashApp", name="ClashApp@yahoo.com")
class HelloWorld{
}
public class Test{
public static void main(String[] args) throws Exception{
Class cl = Class.forName("HelloWorld");
AnnotationInfo ann = (AnnotationInfo) c.getAnnotation(AnnotationInfo.class);
System.out.println("Annotation Information for " + cl);
System.out.println("annotation: " + ann.annotation());
System.out.println("name: " + ann.name());
System.out.println("Version: " + ann.version());
}
}
In the code snippet above, the @Documented annotation indicates it is to show up in the javadocs and the @Retention annotation indicates metadata to be exposed at runtime.
*****Pointers
Java does not permit pointers or pointer-arithmetic within the Java runtime environment. The Java language designers reasoned that pointers were one of the primary features that enable programmers to inject bugs into their code and chose not to support them. Java does not allow for directly passing and receiving objects/structures to/from the underlying operating system and thus does not need to model objects/structures to such a specific memory layout, layouts which frequently would involve pointers. Java's communication with the underlying operating system is instead based upon JNI where communication with/adaption 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 does not permit pointers. However, because pointers are required when calling many native functions, pointers are actually allowed in an explicit "unsafe" mode. Code blocks or methods that use the pointers must be marked with the unsafe keyword to be able to use pointers, and the compiler requires the /unsafe switch to allow compilation of such code. Assemblies which are compiled using the /unsafe switch are marked as such and may only execute if explicitly trusted. This allows programmers to use 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 at the same time isolate such potentially unsafe code in specifically trusted assemblies.
To write unsafe code, the unsafe keyword must be used to specify the code block as unsafe and the program must be compiled with the /unsafe compiler switch.
Since garbage collection may relocate managed (i.e. safe) variables during the execution of a program, the fixed keyword is provided so that the address of a managed variable is pinned during the execution of the parts of the program within the fixed block. Without the fixed keyword there would be little purpose in being able to assign a pointer to the address of a managed variable since the runtime may move the variable from that address as part of the mark & compact garbage collection process.
C# Code
using System;
class UnsafeCode{
public static unsafe void Swap(int* numOne, int*numTwo){
int temp = *numOne;
*numOne = *numTwo;
*numTwo = temp;
}
public static unsafe void Sort(int* array, int size){
for(int i= 0; i < size - 1; i++)
for(int j = i + 1; j < size; j++)
if(array[i] > array[j])
Swap(&array[i], &array[j]);
}
public static unsafe void Main(string[] args){
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Console.WriteLine("Unsorted Array:");
foreach(int x in array)
Console.Write(x + " ");
fixed( int* iptr = array ){
Sort(iptr, array.Length);
}
Console.WriteLine("\nSorted Array:");
foreach(int x in array)
Console.Write(x + " ");
}
}
In the code snippet above, the unsafe Sort method is indicated by the unsafe keyword while pinning the address of the managed array variable during the execution of the parts of the program the fixed keyword is used.
Comments
Post a Comment