From C# To Java: Events

I have been developing in C# for the last 3-4 years, and before that I was primarily a php coder. During one semester of my freshman year of college I did a little Java, but not much, and I have not done any since. I have decided to work on an N-Tier application in Java to give me a good project under my belt and show that I can use Java (and not just say to people that I can learn Java).

The problem with going from C# to Java is that the language is very similar. This is a problem because while I can figure out the language itself pretty easily, most “getting started” guideand tutorials are too beginner level to really be helpful. However, jumping straight into something such as a Spring framework tutorial or many other more high level tutorials can be pretty overwhelming, as they all assume a general knowledge of Java concepts that are not immediately obvious by just looking at a C# to Java language guide. Therefore, I decided to write a series containing conceptual differences or stumbles I find on my journey through implementing a Java application.

Events in C#

The first conceptual hurdle I came across was dealing with Events. In C#, events are pretty easy to deal with, as an event is can be described as a collection of methods that all conform to a single delegate’s method signature. An example of this, based on a good tutorial on Code Project is:

using System;
namespace wildert
{
    public class Metronome
    {
        public event TickHandler Tick;
        public EventArgs e = null;
        public delegate void TickHandler(Metronome m, EventArgs e);
        public void Start()
        {
            while (true)
            {
                System.Threading.Thread.Sleep(3000);
                if (Tick != null)
                {
                    Tick(this, e);
                }
            }
        }
    }
	
    class Test
    {
        static void Main()
        {
            Metronome m = new Metronome();
            m.Tick += HeardIt;
            m.Start();
        }
		
		private void HeardIt(Metronome m, EventArgs e)
		{
			System.Console.WriteLine("HEARD IT");
		}
    }
}

This is essentially adding the HeardIt method to the Metronome.Tick event, so whenever the event is fired, it calls theTest.HeardIt() method (along with any other method attached to the event). This is pretty straightforward in my (biased) opinion.

Events In Java

I started reading some pages on the net about how events in Java are handled. The first few articles I came across were kind of confusing and all over the place. I felt like I almost understood how it’s done but I was missing one piece of crucial information that binds it all together for me. After reading a few more articles, I finally had my “Ah ha!” moment, and it all clicked.

The confusion was due to that fact that unlike in C#, there is no event keyword in Java. In fact, and this is the piece I was missing, there essentially is no such thing as an event in Java. In Java you are essentially faking events and event handling by using a standard set of naming conventions and fully utilizing object-oriented programming.

Using events in java is really just a matter of defining an interface that contains a method to handle your event (this interface is known as the listener interface). You then implement this interface in the class that you want to handle the event (this is the listener class). In the class that you wish to “fire off” the event from you maintain a collection of class instances that implements the listener interface, and provide a method so listener classes can pass an instance of themselves in to add and remove them from the collection. Finally, the act of firing off events is merely going through the collection of listener classes, and on each listener call the listener interface’s method. It’s essentially a pure-OOP solution masquerading as an event handling system.

To see this in action, let’s create the equivalent of the C# event example in Java.

package com.kalldrexx.app

// Listener interface 
public interface MetronomeEvent {
	void Tick(Date tickDate);
}

// Listener implementation
public class MainApp implements MetronomeEvent {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        EventFiringSource source = new EventFiringSource();
		source.addMetronomeEventListener(this); // Adds itself as a listener for the event
		source.Start();
    }
	
	public void Tick(Date tickDate)
	{
		// Output the tick date here
	}
}

// Event source
public class EventFiringSource {

	// Our collection of classes that are subscribed as listeners of our
    protected Vector _listeners;
	
	// Method for listener classes to register themselves
	public void addMetronomeEventListener(MetronomeEvent listener)
	{
		if (_listeners == null)
			_listeners = new Vector();
			
		_listeners.addElement(listener);
	}
	
	// "fires" the event
	protected void fireMetronomeEvent()
	{
		if (_listeners != null && _listeners.isEmpty())
		{
			Enumeration e = _listeners.elements();
			while (e.hasMoreElements())
			{
				MetronomeEvent e = (MetronomeEvent)e.nextElement();
				e.Tick(new Date());
			}
		}
	}
	
	public void Start()
	{
		fireMetronomeEvent();
	}
}

When the app starts (and enters the MainApp’s main() method), it creates the event source and tells it that the MainApp class should be registered as a listener for the Metronome event. When the event source class starts, it will “fire” off the event by just looking at all classes registered that implement the MetronomeEvent interface, and call the Tick() method for that implemented class.

No special magic, just pure object-oriented programming!

Advertisements

19 responses to “From C# To Java: Events

  1. Great article! It helped me to understand the events in Java right away. Thank you! 🙂

    Btw. I suppose there should be ‘implements MetronomeEvent’ without ‘s’.

  2. For a C# programmer, looking to it I just concluded that java DOES NOT have events, we can only provide events behavior. 😦

  3. you forgot to negate _listeners.isEmpty() in line 44.
    anyways, thank you very much for this simple solution! kinda opened my eyes.
    Still not satisfied though, for me it’s too much code on the source side.. i’d have to declare a fire event for every event (if the object fires more than one type of events), and all these fire methods would have almost identical code in them..

    • Ah good catch.

      I agree. I started playing with Java so I could put on my resume that I could learn other languages and prove it. Soon after writing this I got a job and I find Java way too verbose (compared to c#) for me to have a real desire to continue playing with it.

  4. Beautiful, exactly wht i was looking for. As a c# programmer taking a java course in school this semester. Event handling in java seemed annoying to me buh this has helped me a lot. Thanks.

    • I develop in neither but must say the author’s //comments are not considered ‘Java’ code; the c# does not contain any comments. Moreover, you may not understand much about programming if you believe one language is the ‘winner’ when it can implement something using five less lines of code.

    • That’s
      Strip away 9 comment lines in Java (C# doesn’t have them) and then 8 lines of source code that isn’t really needed (all the null/empty list checks that could be avoided by just creating an empty list at first) and you’re left with 42 vs 36.

      Still not a good comparison since they don’t do the same thing (no event sending loop in java), but it seems to me the examples were written to make a point, not to make a fair comparison.

  5. I’m in the same boat (C# to Java). This was helpful, thanks!
    By the way, line 44, there should be a “!” in front of “_listeners.isEmpty()”, right?
    It’s obvious what the code is supposed to do, I’m just being pedantic.

  6. Well, isn’t it just an observer pattern implementation (can do the same in .Net langs of course), but delegates in .net are more in turns than just for event (like for async an so on)

  7. This is how events were implemented in C++ as well. It’s called the callback pattern: http://en.wikipedia.org/wiki/Callback_%28computer_programming%29

    There’s no avoiding it in Java, until Java gets something equivalent to C#’s delegates or lambda expressions. Java was SUPPOSED to get lambda expressions in Java 7 (see ex. http://stackoverflow.com/questions/3408361/complexity-of-java-7s-current-lambda-proposal-august-2010 ), but I guess that feature was quietly dropped? Which is unfortunate, because that was by far the most useful and wanted feature.

    • The main difference is that with C# events, it’s keeping track of a list of Delegates rather than class instances. Other than that though you are correct, c# is providing a more abstracted way of keeping track of a list of methods that can be called to execute without having to code it manually.

  8. In Java 8, the code can be simplified using the lambda, streams, and pipeline features:

    if (_listeners != null && _listeners.isEmpty())
    {
    Enumeration e = _listeners.elements();
    while (e.hasMoreElements())
    {
    MetronomeEvent e = (MetronomeEvent)e.nextElement();
    e.Tick(new Date());
    }
    }

    can be changed to

    if (_listeners != null)
    {
    _listeners.parallelStream().forEach(ell -> ell.Tick(new Date()));
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s