Introduction
C# language has come up with some very beautiful features where Java is lacking. People are still able to manage but having those in Java would make life of the developers much easier. Recently, I found Javassist library which is able to manipulate bytecode and compile classes at runtime. Using that, I was able to implement some of the features.
Delegate
A delegate is a type that references a method.
C# declaration:
public delegate int PerformCalculation(int x, int y);
Equivalent Java declaration:
public abstract class PerformCalculation extends csharp.Delegate {
public abstract int invoke(int x, int y);
}
C# instantiation:
PerformCalculation performCalculation = new PerformCalculation(this.myMethod);
PerformCalculation performCalculation = new PerformCalculation(AClass.myMethod);
Equivalent Java instantiation
PerformCalculation performCalculation = Delegate.<PerformCalculation>
getInstance(PerformCalculation.class, this, "myMethod");
PerformCalculation performCalculation = Delegate.<PerformCalculation>
getInstance(PerformCalculation.class, AClass.class, "myMethod");
You can just call invoke of the performCalculation
object. A new delegate class is created on runtime for each AClass
type used (but only once throughout the life of the application).
Requirements
- The declared '
Delegate
' class and 'invoke
' method should be 'public abstract
'. - Signature of the '
invoke
' method should match to that of 'myMethod
' function. - Only one '
invoke
' method should be present. - It would be better if '
myMethod
' function is public
or protected
else reflection is used which may have performance issues.
Event
An event
in C# is a way for a class to provide notifications to clients of that class when some interesting thing happens to an object. This is actually list of delegates.
C# declaration/instantiation:
public event PerformCalculation myEvent;
Equivalent Java declaration:
public abstract class MyEvent<D extends PerformCalculation> extends csharp.Event<D> {
public abstract int invoke(int x, int y);
}
Equivalent Java instantiation:
MyEvent<PerformCalculation> performEvent =
Event.<MyEvent<PerformCalculation>> getInstance(MyEvent.class, PerformCalculation.class);
You can now add PerformCalculation
delegates to performEvent
object by calling its 'add
' method. Calling invoke of the performEvent
object which will call invoke of all the delegate
s added.
Requirements
- The declared '
Event
' class and 'invoke
' method should be 'public abstract
'. - Signature of the '
invoke
' method should match that of delegates to be added. - Only one '
invoke
' method should be present.
Pass by ref
The ref
keyword in C# causes an argument to be passed by reference. This feature is not available in Java. It means if this is available in future, primitive types will be passed by reference and objects will be passed by reference of a reference (by default, reference of object is passed).
So, following would not change the original variable.
list = new ArrayList();
But the 'list
' variable will point to a new memory location. For this, I have included few wrapper classes (one of each primitive type and one with generics for objects) in my code that can be used to pass reference and get it back. This is nothing new but included them in the code just in case somebody wants to use this feature.
Notes
If you are a hardcore Java developer, please read about events and delegates. You may not appreciate these features till you have actually used them in your code.
Update
- Use of
class.getCanonicalName
instead of class.getName
. The latter had issues in case of inner classes. - There is no need of writing dynamically compiled classes to
filesystem
.
History
- 15th May, 2012: Initial version