Conversion of code written in one language to another requires a good understanding of
features supported in both the languages in consideration. Apart from knowing the
features supported in one language it is imminent to know the equivalence of that feature
in the other language for effective and successful code conversion. It is quite possible to
have a situation where the exact equivalent features are not available in the languages
under consideration for conversion. So it requires knowledge on the workarounds in the
other language to make sure the code conversion is correct. Therefore for an effective and
correct conversion of code between the languages the following things needs to be
considered:
Good knowledge of the features supported in both the source and target language.
Knowing the equivalence of the required features in the source and target
language.
Ability to have a work around for the code conversion in case of non-availability
of the equivalent features in source and target language.
The objective of this document is to give the methodologies, references , alternatives and
complexities in converting code from C# to Java. The document is filled with practical
illustrations to make the conversion simpler for the users.
Java and C# are strongly typed object oriented languages developed by Sun and
Microsoft respectively. C# has a combination of C++ and Java features plus some
additional new features.
As we proceed further we will be covering first the syntactical equivalence of some of
features in C# and Java .The complexities we faced in our project and the solutions to
overcome the complexities in converting some of the features will be covered next. The
complexities include the code conversion of the following features like getters and
setters, generic type, attribute, event handling, name clash problem in inherited class,
static constructor from C# to Java. We hope that the document will serve as a good
reference guide for the conversion project from C# to Java.
Conversion of equivalence features in C# and Java
The conversion discussed is from C# 2.0 to Java 1.5
Here we give you the conversion reference of some of features available in C# which has
direct equivalent features in Java. Any code that has these features in C# can be directly
converted to its equivalent code in Java just by directly replacing its Java equivalent.
File Naming Conventions
Java:
Source files are denoted by .java extn.
Each source file contains one top level public class declaration, and the
file name should match the class name.
C#:
Source files are denoted by .cs extn.
Each source file can contain more than one top level public class
declaration, and the file name doesn’t need to match the class name.
Comments
Java:
Single line comment
//test
Multiline comments
/*
test
*/
Documentation comments
/**
* test
*/
C#:
Single line comment
//test
Multiline comments
/*
test
*/
Documentation comments
///<summary>
///test
///</summary>
Main()
Java:
- public static void main(String[] args)
- static public void main(String[] args)
- static void main(String[] args)
- public static void main(String… args)
C#:
• public static void Main(string[] args)
(or)
public static void Main()
• internal static void Main(string[] args)
(or)
internal static void Main()
• static void Main(string[] args)
(or)
Static void Main()
Print Statements
Java:
System.out.println(“Hello World”);
C#:
System.console.writeLine(“Hello World”);
Constants Declaration
Java:
static final int k =100;
C#:
const int k=100;
Inheritance
Java:
Class B extends A implements Comparable
{
}
C#:
Class B: A, IComparable
{
}
(In C#, the interface name should start with “I” it is a naming convention)
Declaration and Initialization of Arrays
Java:
In Java we can declare the arrays in either way. But in C#,we can declare
it only by the first way. The second way gives a compilation error.
float [] farr1=new float [10]; //valid
float farr2[] = new float[10]; //valid
C#:
float []farr1=new float [10]; //valid
float farr2[] = new float[10]; //invalid. Compilation error
C# array elements can be initialized at creation using the same syntax as in Java.
int[] testArr;
testArr=new int[3]{1,2,3}
Unlike Java, in C# the number of initializers must exactly match the array size.
String Comparison
Java:
String values are compared by using .equals() method
C#:
String values are compared by using == &! = operators. Also strings can
be compared using Object.equals (String1, String 2)
Switch Statements
Java:
Doesn’t support the use of string literals.
switch(value) { case 1: System.out.println(“1”); case 2: System.out.println(“2”); default: System.out.println(“default”); break; }
Since it doesn’t have the “break” statements after each case, it should
execute the code in the next cases up to the point where it reaches the break statement.
Both languages support Enums
C#:
switch (value) { case 1: System.Console.WriteLine (“1”); case 2: System.Console. WriteLine (“1”); default: System.Console. WriteLine (“default”); break ; }
Here we will get a compilation error, because c# doesn’t allow a fall through from one
case label to another case label.
But C# allows a fall through for the switch statements, provided when you don’t add any
logic into the case statements.
A valid example,
switch (value) { case 1: case 2: default: System.Console. WriteLine (“default”); break ; }
Enums
Java:
Ordinary enums
enum Action{Start,Stop,Rewind,Forward}
Special kind of enums
enum Status { Flunk(50), Pass(70), Excel(90); private final int value; Status(int value) { this.value = value; } public int value() { return value; } }; Action a = Action.Stop; if (a != Action.Start) System.out.println(a); // Prints "Stop" Status s = Status.Pass; System.out.println(s.value()); // Prints "70"
Here Status (int value) constructor is defined because, Flunk(50),
Pass(70), Excel(90) will make a call to constructor.
Public int value() method is defined, which is used to access the values
declared for Flunk, Pass, Excel ie.., 50,70,90
C#:
Ordinary enums
enum Action{Start,Stop,Rewind,Forward}
Special kind of enums
enum Status {Flunk = 50, Pass = 70, Excel = 90}; Action a = Action.Stop; if (a != Action.Start) Console.WriteLine(a); // Prints "Stop" Status s = Status.Pass; Console.WriteLine((int) s); // Prints "70"
Here,we can directly assign the values to Flunk,Pass,Excel and we can also get
the values directly without using constructors or a method call.But it needs a type cast to
print the values.
For Loops
Java:
public static void main(String ar[]) { int[] arr=new int[]{1,2,3,4,5}; for(int i: arr) { System.out.println(“values in array are::”+ i); } }
C#:
public static void Main() { int[] arr=new int[]{1,2,3,4,5}; foreach(int i in arr) { Console.WriteLine (“values in array are:”+ i.ToString ()); } }
Is operator Vs instanceof
C#:
public void CheckType(Object obj) { if(obj is int) { Console.WriteLine(“Integer parameter”); } if(obj is float) { Console.WriteLine(“Float parameter”); } }
Java:
The same can be achieved in Java using instanceof operator
public void checkType(Object obj) { if(obj instanceof Integer) { System.out.println (“Integer parameter”); } if(obj instanceof Float) { System.out.println (“Float parameter”); } }
In C# both the objects and primitive types can be used along with the “is” operator but in
java only Objects are allowed with “instanceof” operator and so the corresponding
wrapper classes are used instead of primitive types. For example int and float are
wrapped into wrapper classes Integer and Float.
“as” operator in C#
“as” operator is similar like “is” operator. It is used in the type casting, it returns
null on the conversion failure instead of raising the exception.
public void CheckType(Object obj) { if((obj as int) !=null) { Console.WriteLine(“Integer parameter”); } }
“as” Operator in C# does two functions
1. The Type Comparison
2. The type casting
int i = obj as int;
The above code is equivalent to
if(obj is int) // Type Comparison
{
int i = (int)obj; // Type casting
}
There is no alternative for the “as” operator in java, but the functionality can be
implemented using the “instanceof” operator for type comparison and the casting must be
explicitly done. In case of java if the type casting fails then a ClassCastException is
thrown at runtime, so a type check before type casting makes code safer.
Java Alternatives for .net classes
Complexities in Conversion
Getters and Setters in Java and .Net (Properties)
In C#, properties are nothing but natural extension of data fields. They are
usually known as 'smart fields' in C# community. Properties are defined using the
property declaration syntax. There is no concept of Properties in java but the getter and
setter methods act as the alternatives.
C# code snippet:
using System; class MyClass { private int x; public int X { get { return x; } set { x = value; } } } class MyClient { public static void Main() { MyClass mc = new MyClass(); mc.X = 10; int xVal = mc.X; Console.WriteLine(xVal);//Displays 10 } }
Java code snippet:
class MyClass { private int x; public void setX(int i) { x = i; } public int getX() { return x; } } class MyClient { public static void main(String args[]) { MyClass mc = new MyClass(); mc.setX(10); int xVal = mc.getX(); System.out.println(xVal);//Displays 10 } }
Attributes
Attributes provide a powerful method of associating declarative information with
C# code. Declaring an attribute in C# — it takes the form of a class declaration that
inherits from System.Attribute. The declaration and the usage are given below. In java
this can be accomplished using annotations.
C# code snippet:
public class HelpAttribute : System.Attribute
{
public readonly string Url;
public HelpAttribute(string url) // url is a positional parameter
{
this.Url = url;
}
}
Usage
[HelpAttribute("http://localhost/MyClassInfo")]
class MyClass
{
}
Java code snippet:
public @interface HelpAttribute
{
public String Url();
}
Usage
@ HelpAttribute (Url = “http://localhost/MyClassInfo”)
class MyClass
{
}
Event Handling
In C#:
Event-driven programming is a programming model where objects can register
themselves to be notified of a specific occurrence or state change in another object.
Event-driven programming is also referred to as the publish-subscribe model or the
observer design pattern and is very popular in graphical user interface (GUI)
programming. Java and C# both have mechanisms that support events but there are
significant differences. The typical publish-subscribe model has a one to many
relationship between an object (publisher) and its event handlers (subscribers). A
subscriber is registered by invoking a method on the publisher which then adds the
subscriber to an internal collection of interested objects. When the state change that a
registered subscriber is interested in occurs, a method is invoked in the publisher that
cycles through the collection of subscribers and invokes a callback method on each one.
C# uses delegates to provide an explicit mechanism for creating a publish-subscribe
model. An event is typically a subclass of the System.EventArgs class.
Like all data classes, the event class should have a constructor that allows
complete initialization without calling any other methods so that you can pass
new YourEventArgs(inits) to the subscriber delegate.
The publisher has a protected method preceded with the word "On" (e.g. OnClick,
OnClose, OnInit, etc) which is invoked when a specified event occurs, this
method would then invoke the delegate passing it the source and an instance of
the EventArgs object. Making the method protected allows derived classes to call
it directly without the need to register a delegate.
The subscriber is a method that accepts the same argument and returns the same
type as the event delegate.
The event delegate usually returns void and accepts two parameters; an Object
which should be the source of the event and the EventArgs subclass which should
represent the event that occured.
In C#, the event is used to automatically specify that a field within a subscriber is
a delegate that will be used as a callback during an event-driven situation. During
compilation the compiler adds overloaded versions of the += and -= operators that are
analogous to the add and remove methods that are used in Java to register and unregister
a subscriber.
The example below shows a class that generates 20 random numbers and fires an
event whenever one of the numbers is even.
The procedure of creating a custom event and handling it is different in java and
.net. The event handling in .net involves a “deligate” and “Event”. While in java it
includes an interface and a class which has a vector to store the listeners. It is important
to understand the procedure of event handling in both java and .net in order to convert
any such code from .net to java.
C# code snippet:
using System;
class EvenNumberEvent: EventArgs{
/* fields are typically private, but making this internal so it
* can be accessed from other classes. In practice should use properties.
*/
internal int number;
public EvenNumberEvent(int number):base(){
this.number = number;
}
}
class Publisher{
public delegate void EvenNumberSeenHandler(object sender, EventArgs e);
public event EvenNumberSeenHandler EvenNumHandler;
protected void OnEvenNumberSeen(int num){
if(EvenNumHandler!= null)
EvenNumHandler(this, new EvenNumberEvent(num));
}
//generates 20 random numbers between 1 and 20 then causes and
//event to occur if the current number is even.
public void RunNumbers(){
Random r = new Random((int) DateTime.Now.Ticks);
for(int i=0; i < 20; i++){
int current = (int) r.Next(20);
Console.WriteLine("Current number is:" + current);
//check if number is even and if so initiate callback call
if((current % 2) == 0)
OnEvenNumberSeen(current);
}//for
}
}//Publisher
public class EventTest{
//callback function that will be called when even number is seen
public static void EventHandler(object sender, EventArgs e){
Console.WriteLine("\t\tEven Number Seen:" +
((EvenNumberEvent)e).number);
}
public static void Main(string[] args){
Publisher pub = new Publisher();
//register the callback/subscriber
pub.EvenNumHandler += new
Publisher.EvenNumberSeenHandler(EventHandler);
pub.RunNumbers();
//unregister the callback/subscriber
pub.EvenNumHandler -= new
Publisher.EvenNumberSeenHandler(EventHandler);
}
}
In Java
There is no general mechanism for event handling in Java. Instead there are
design patterns that are used by the GUI classes which developers can take their cue
from. An event is typically a subclass of the java.util.EventObject class, which has
methods that enable setting or getting of the object that was the source of the event. A
subscriber in the Java model usually implements an interface that ends with the word
Listener (e.g. MouseListener, ActionListener, KeyListener, etc) which should contain a
callback method that would be called by the publisher on the occurrence of the event. The
publisher typically has a method that begins with add and ends with Listener (e.g.
addMouseListener, addActionListener, addKeyListener, etc) which is used to register
subscribers. The publisher also has remove methods for unregistering the subscribers.
The aforementioned components are the primary entities in an event-driven Java
program.
Java code snippet:
import java.util.*;
class EvenNumberEvent extends EventObject{
public int number;
public EvenNumberEvent(Object source, int number){
super(source);
this.number = number;
}
}
interface EvenNumberSeenListener{
void evenNumberSeen(EvenNumberEvent ene);
}
class Publisher{
Vector subscribers = new Vector();
private void OnEvenNumberSeen(int num){
for(int i=0, size = subscribers.size(); i < size; i++)
((EvenNumberSeenListener)subscribers.get(i)).evenNumberSeen(new
EvenNumberEvent(this, num));
}
public void addEvenNumberEventListener(EvenNumberSeenListener ensl){
subscribers.add(ensl);
}
public void removeEvenNumberEventListener(EvenNumberSeenListener
ensl){
subscribers.remove(ensl);
}
//generates 20 random numbers between 1 and 20 then causes and
//event to occur if the current number is even.
public void RunNumbers(){
Random r = new Random(System.currentTimeMillis());
for(int i=0; i < 20; i++){
int current = (int) r.nextInt() % 20;
System.out.println("Current number is:" + current);
//check if number is even and if so initiate callback call
if((current % 2) == 0)
OnEvenNumberSeen(current);
}//for
}
}//Publisher
public class EventTest implements EvenNumberSeenListener{
//callback function that will be called when even number is seen
public void evenNumberSeen(EvenNumberEvent e){
System.out.println("\t\tEven Number Seen:" +
((EvenNumberEvent)e).number);
}
public static void main(String[] args){
EventTest et = new EventTest();
Publisher pub = new Publisher();
//register the callback/subscriber
pub.addEvenNumberEventListener(et);
pub.RunNumbers();
//unregister the callback/subscriber
pub.removeEvenNumberEventListener(et);
}
}
Name clash problem from inherited classes
In .net the method name can be qualified in the classes which implements the methods of
an interface, but in java method name cannot be qualified. So problem arises when there
are two interfaces which have one or more methods with same method signature and are
both implemented by a class. Name clash occurs because of the ambiguity caused due to
same method signature. This problem can be solved in Java, only by changing name of
the method in any one of the interfaces so that name clash is avoided.
C# Snippet:
interface A
{
void OneMethod();
}
interface B
{
void OneMethod();
}
class C : A,B
{
public void A.OneMethod()
{ ………
………
}
public void B.OneMethod()
{ ………
………
}
}
Java Snippet:
interface A
{
void oneMethod();
}
interface B
{
void twoMethod(); // name of the method changed
}
class C implements A,B
{
public void oneMethod() // Method from interface A
{ ………
………
}
public void twoMethod() // Method from interface B
{ ………
………
}
}
Static Constructors
C# Snippet:
class StaticTest
{
static StaticTest()
{
Console.Writeln(“Static Constructor in C#”);
}
}
Java Snippet:
class StaticTest
{
static
{
System.out.println(“Static Block in Java”);
}
}
Generics
In .net there is a possibility of knowing the generic type of the method or a class
at the run time by using typeof (T) where T is the generic type, and there is a possibility
of checking whether the generic type is of a specific type or not by using if (obj is T) as
shown below in the snippet.
C# generic class
class GenericClass<T>
{
Type type = typeof(T);
public GenericClass() //constructor
{
}
}
C# generic method
void GenericMethod<T> (T t)
{
T newInstance = new T ();
Type type = typeof(T);
List<T> list = new List<T> ();
if (list is List<String>) {}
}
In Java, the type of the generic type cannot be known by using T as in C# .Class
or the type cannot be checked using if (obj instanceof T) .The work around is to add an
extra parameter to the method which holds the type information.
If it is a generic class, add a parameterized constructor and pass the type of the
generic class as a parameter to the constructor and the type information from the
constructor parameters must be stored in instance variables which can be used when
required.
If it is a generic method, pass the type of the generic method as a parameter to the
method.
Java Work around for generic Class
class GenericClass<T>
{
Class type; // Variable to preserve the Type information
public GenericClass(Class t) // Parameterized constructor
{
type = t;
}
}
Java Work around for generic Method
void genericMethod<T> (Class t) // New Parameter added to pass the Type
information
{
Class type = t;
}