Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News

SYS-CON.TV
Cloud Expo & Virtualization 2009 East
PLATINUM SPONSORS:
IBM
Smarter Business Solutions Through Dynamic Infrastructure
IBM
Smarter Insights: How the CIO Becomes a Hero Again
Microsoft
Windows Azure
GOLD SPONSORS:
Appsense
Why VDI?
CA
Maximizing the Business Value of Virtualization in Enterprise and Cloud Computing Environments
ExactTarget
Messaging in the Cloud - Email, SMS and Voice
Freedom OSS
Stairway to the Cloud
Sun
Sun's Incubation Platform: Helping Startups Serve the Enterprise
POWER PANELS:
Cloud Computing & Enterprise IT: Cost & Operational Benefits
How and Why is a Flexible IT Infrastructure the Key To the Future?
Click For 2008 West
Event Webcasts
Restoring the "Delegate" Concept To Java
Had the "Delegate" Become Part of Java, Would Swing Programming Be Easier?

The function pointer, a powerful concept in the C and C++ programming languages, has no direct equivalent in Java. No syntax exists to pass the address of a method to a JButton, for instance, that links it with pressing the button. Instead, Java promotes the use of anonymous inner classes, like this one:


okButton.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    startProcessing();
  }
});

Back in October 1996, in an attempt to eliminate the need for this bloated syntax, Microsoft introduced an object-oriented method pointer into J++ called a "delegate." Sun Microsystems, citing the delegate as language pollution, sued Microsoft a year later for violating its Java license agreement. The lawsuit successfully maintained the purity of Java, but it also encouraged Microsoft to develop a competing Java-like language, C#. Today, the delegate lives on in C# and the other .NET programming languages that comprise Microsoft's Common Language Runtime.

Had the delegate become part of Java, would Swing programming be easier? More than simply hooking a component to an action, the delegate could invoke methods directly or asynchronously on a worker thread. Could that technique have solved many of the Swing threading headaches that we're faced with today? This article explores these possibilities by using Java's reflection API to restore the delegate concept to Java.

Building a Delegate
java.lang.reflect.Method provides a description of a method including formal parameter types, return type, access modifier, declared exceptions, and annotations. It also provides an invoke() method to perform an indirect call; however, unlike a function pointer, Method is not bound to a particular object instance. It's part of a toolkit that includes Constructor and Field for inspecting classes. To use invoke() you must pass in a reference to an object instance.

Listing 1 demonstrates how to use it to call System.out.println() indirectly. Since the static member variable out is an instance of PrintStream, Line 4 calls getMethod() on the PrintStream Class passing in a description of the method that we're interested in. Note, many of the reflection API methods were retrofitted with varargs as of Java 5; previously, getMethod() accepted the method name followed by the method parameter types as a Class[]. Line 8 passes the string to print along with out to invoke() on the Method acquired in line 4.

To build a Delegate class, I joined together a Method and an object instance. Compare Listing 1 to the following snippet:


Delegate delegate = new Delegate(
  System.out, "println");
delegate.invoke("Hello World!");

First, notice the lack of exception handling. Internally, Delegate transforms checked exceptions into unchecked exceptions for cleaner code. Second, observe that when Delegate is constructed, the println() method is not fully described; the parameter types are absent. Delegate.invoke() completes the method resolution on the first call using getClass() on each argument. Subsequent calls reuse a cached Method; however, this technique, although convenient, fails when a null parameter is used on the initial call. An alternative constructor lets you specify the argument class types explicitly like this:


Delegate delegate = new Delegate(
  System.out, "println", String.class);
delegate.invoke("Hello World!");

Delegate seeks out and binds to methods of any access level, including private ones. Instead of using Class.getMethod(), which obtains only public methods, Delegate calls Class.getDeclaredMethod(). Unfortunately, both of those functions exclude inherited methods. To get around that, Delegate iteratively applies getDeclaredMethod() to all the classes in the hierarchy with the aid of Class.getSuperclass(). After locating the method of interest, Method.setAccessible(true) is used to suppress invocation access checking.

If you're surprised that you can call a private method from outside of an object, recognize that access modifiers were designed for code organization, not for security; they enable you to expose usage method while hiding implementation details. Suppressing access checking is highly beneficial for unit testing. Normally to unit test implementation methods, you have to grant them at least default (package) access; however, Delegate provides an alternative that lets you keep those methods private.

Since static methods are bound to classes, not instances, Delegate provides another constructor, which accepts a Class. The following example creates a Delegate to the Math.cbrt() function, a static method introduced in Java 5 to compute cube roots.


Delegate delegate = new Delegate(Math.class, "cbrt");
double x = (Double)delegate.invoke(8.0);

Delegate.invoke() returns type Object; in this case, the result is first cast to Double and then auto-unboxed to a double primitive.

About Michael Birken
Michael Birken is actively involved in the design and research of emerging trading technologies at a Manhattan-based financial software company. He's a Sun Certified Java programmer and developer. Michael holds a BS in computer engineering from Columbia University.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1

Hi!
I don't really see the point of using delegates in java. The code with ActionListeners is more clear to me than using some function pointer, and passing them into UI elements. It implements observer/obesrvable pattern, and it's more objective for me than delegates... You can easily implement your won calls that will implement this pattern just by having a list of objects that implemet some interface and invoking it's method, nothing more....
And when I saw how my collegue tries to implemet his won delegates in C# it was very difficult to me to understand what his trying to do (he also didn't know it... :D )

Have a nice day

Oh, another suggestion is to use a more Microsoft alike approach. For example when instead of:

container.add(button)

the following is writen:

container.add(SwingEventDispatcher.wrap(button, "store", this));

This line still adds the button to the container, but also names the button "store" and binds it to "this" by searching for methods with a particular pattern, for example:

public void store_actionPerformed(ActionEvent e)

Note the "store_" prefix. To make the source more readable this method may also be written as:

public void store_clicked(ActionEvent e)

And some intelligence is added also:

public void store_singleClick(ActionEvent e)
public void store_doubleClick(ActionEvent e)
public void store_tripleClick(ActionEvent e)
public void store_multiClick(ActionEvent e)

It makes sure that on a double click only xxx_doubleClick is called and not xxx_singleClick also.

The same trick works with all events:

mybean_propertyChanged(PropertyChangeEvent e)
mylist_selectionChanged(...)
...

A cleaner solution (IMHO) are closures. Using closures would result in something like:

JButton button = new JButton();
button.addActionListener() { e | button.setText("bla"); }

Closures basically are inner classes that can access its context without having to use final (the local variable button is used in the inner class). Groovy provides a (hopefully soon) standard way to do this, but at least Groovy is fully Java compatible.

Maybe I'm not following the argument here, but I guess I wonder why someone would prefer to pass around function pointers rather than interfaces. Can't the dispatch code just as easily invoke a method through an interface as through a Delegate class?

I guess I am uncomfortable with the modularity here. First of all, actual implementation classes have a sort of rigidity from the standpoint of the client and the programmer. So I like having interfaces anyway. But the other issue is that a method may start out being 'standalone', but then it may need to be called as part of a sequence of other methods. If you delegate through Interfaces, then it would seem you could add those other methods very easily.

Finally, variable argument lists are prone to incorrect use in all circumstances; but in this one there is no commonalties among the arguments. The classic 'printf' variety of variable argument lists was very clear -- each of the variable arguments is intended to be rendered as text. In this case it can be results of embedded function calls or anything. I guess I don't understand why one would want to suppress type checking.

Anyway I have really not gotten the idea or the benefit of this technique. Sometimes it's worthwhile to emulate one language's constructs in another language, but I don't see it here.

There's nothing wrong with inner classes per se; they represent a superset of the functionality of delegates or method pointers. The problem is the Java language itself, and the lack of lightweight anonymous function/class declaration, and the lack the type inferencing. Fix those two things and the ugly part of inner classes (the declaration syntax) goes away.

Scala does lightweight functional syntax very nicely. If func takes something like an action listener, you can call it like this (for arrow read greater-equals):

func(event "arrow" event.getComponent().setSelected(true));

Scala knows the expected type for the call and builds the scaffolding necessary. Under the covers you end up with:

func(new ActionListener() {
public void actionPerformed(Event event) {
event.getComponent().setSelected(true)
}});

The Buoy package contains some things similar to what you've outlined in your article. Although I have not worked with, reading the examples makes it appear that your goals of making the event handling code easier exists already in Buoy.

One of the things I miss the most about C is the lack of pointers to functions. Used correctly, these are fantastically useful. Hopefully, some of that can be added back (or implemented as is shown here) for the greater good of all.

Remember too, the 'Evil Empire' did not invent this desire (as noted by a previous respondent) they only implemented a shortcoming that they saw. This is not a bad thing.

### Dennis Farr commented ...
Great article. I have been haunted by the thought that not all differences between C# and Java were abberations, and your article shows how to take advantage of the good ideas coming out of the evil empire and use them inside Java. ###

The idea is certain to provoke widepsread discussion - it reminds how close C# and Java are.

Great article. I have been haunted by the thought that not all differences between C# and Java were abberations, and your article shows how to take advantage of the good ideas coming out of the evil empire and use them inside Java. Java is at least open enough to discuss and use ideas from outside Sun, as I hope yours will be.


Your Feedback
Black007_pl wrote: Hi! I don't really see the point of using delegates in java. The code with ActionListeners is more clear to me than using some function pointer, and passing them into UI elements. It implements observer/obesrvable pattern, and it's more objective for me than delegates... You can easily implement your won calls that will implement this pattern just by having a list of objects that implemet some interface and invoking it's method, nothing more.... And when I saw how my collegue tries to implemet his won delegates in C# it was very difficult to me to understand what his trying to do (he also didn't know it... :D ) Have a nice day
Tom wrote: Oh, another suggestion is to use a more Microsoft alike approach. For example when instead of: container.add(button) the following is writen: container.add(SwingEventDispatcher.wrap(button, "store", this)); This line still adds the button to the container, but also names the button "store" and binds it to "this" by searching for methods with a particular pattern, for example: public void store_actionPerformed(ActionEvent e) Note the "store_" prefix. To make the source more readable this method may also be written as: public void store_clicked(ActionEvent e) And some intelligence is added also: public void store_singleClick(ActionEvent e) public void store_doubleClick(ActionEvent e) public void store_tripleClick(ActionEvent e) public void store_multiClick(ActionEvent e) It makes sure that on a double click only xxx_doubleClick is called and not xxx_singleC...
Tom wrote: A cleaner solution (IMHO) are closures. Using closures would result in something like: JButton button = new JButton(); button.addActionListener() { e | button.setText("bla"); } Closures basically are inner classes that can access its context without having to use final (the local variable button is used in the inner class). Groovy provides a (hopefully soon) standard way to do this, but at least Groovy is fully Java compatible.
A Wolfe wrote: Maybe I'm not following the argument here, but I guess I wonder why someone would prefer to pass around function pointers rather than interfaces. Can't the dispatch code just as easily invoke a method through an interface as through a Delegate class? I guess I am uncomfortable with the modularity here. First of all, actual implementation classes have a sort of rigidity from the standpoint of the client and the programmer. So I like having interfaces anyway. But the other issue is that a method may start out being 'standalone', but then it may need to be called as part of a sequence of other methods. If you delegate through Interfaces, then it would seem you could add those other methods very easily. Finally, variable argument lists are prone to incorrect use in all circumstances; but in this one there is no commonalties among the arguments. The classic 'printf' variety of var...
Ross Judson wrote: There's nothing wrong with inner classes per se; they represent a superset of the functionality of delegates or method pointers. The problem is the Java language itself, and the lack of lightweight anonymous function/class declaration, and the lack the type inferencing. Fix those two things and the ugly part of inner classes (the declaration syntax) goes away. Scala does lightweight functional syntax very nicely. If func takes something like an action listener, you can call it like this (for arrow read greater-equals): func(event "arrow" event.getComponent().setSelected(true)); Scala knows the expected type for the call and builds the scaffolding necessary. Under the covers you end up with: func(new ActionListener() { public void actionPerformed(Event event) { event.getComponent().setSelected(true) }});
Michael Abernethy wrote: The Buoy package contains some things similar to what you've outlined in your article. Although I have not worked with, reading the examples makes it appear that your goals of making the event handling code easier exists already in Buoy.
Kevin Timm wrote: One of the things I miss the most about C is the lack of pointers to functions. Used correctly, these are fantastically useful. Hopefully, some of that can be added back (or implemented as is shown here) for the greater good of all. Remember too, the 'Evil Empire' did not invent this desire (as noted by a previous respondent) they only implemented a shortcoming that they saw. This is not a bad thing.
Javanaut wrote: ### Dennis Farr commented ... Great article. I have been haunted by the thought that not all differences between C# and Java were abberations, and your article shows how to take advantage of the good ideas coming out of the evil empire and use them inside Java. ### The idea is certain to provoke widepsread discussion - it reminds how close C# and Java are.
Dennis Farr wrote: Great article. I have been haunted by the thought that not all differences between C# and Java were abberations, and your article shows how to take advantage of the good ideas coming out of the evil empire and use them inside Java. Java is at least open enough to discuss and use ideas from outside Sun, as I hope yours will be.
Latest Cloud Developer Stories
Swisscom, the Swiss telecom, is going into the cloud business. Its subsidiary Swisscom IT Services AG has signed up with Red Hat as a Certified Cloud Provider and launched a public cloud Infrastructure-as-a-Service (IaaS) cloud targeting enterprise-class customers primarily in ...
Apache Deltacloud, the Red Hat-contributed ReSTful API that abstracts differences between clouds so services on any cloud can be managed – provided of course there’s a driver – has graduated from the Apache Foundation’s incubator and is now a full-fledged Top-Level Project (TLP)....
In a surprise move on Tuesday, January 10, Oracle wheeled out its Big Data Appliance. That’s the one it said in October would be ready sometime in the first half. Only nobody believed it meant early in the first half. Heck, it’s not even clear anybody thought Oracle could make ...
Rackspace Hosting, the service leader in cloud computing, on Thursday announced its acquisition of SharePoint911, an industry leader in SharePoint consulting, training, and "JumpStart" services within SharePoint. The unification of both companies provides capabilities to deliver ...
CloudLinux, Inc., on Thursday released CafeFS 3, a virtualized file system for shared hosters that cages each customer within its own virtualized file system. CageFS becomes part of CloudLinux OS at no additional charge. CloudLinux OS, the only commercially-supported Linux OS m...
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

SYS-CON Featured Whitepapers
ADS BY GOOGLE

Breaking Cloud Computing News

BEACHWOOD, Ohio, Feb. 16, 2012 /PRNewswire/ -- DDR Corp. (NYSE: DDR) today announced operating re...