4 January 2010

Sébastien

,

NetBeans Strikes Back

I am more and more impressed with NetBeans.

I remember toying a long time ago with Forte for Java when it was still a young project. Then I switched to what was at the time the Rolls of the IDEs, Visual Age for Java, whose repository was a royal pain in the arse.

Forte for Java subsequently became NetBeans, and Visual Age had a second birth with the advent of Eclipse. Ever since, I have been using Eclipse which was without contest the best: completion, debugging, nifty Tomcat integration with the Sysdeo plugin, cool profiler, etc.

Now, with more recent versions of Eclipse, getting a J2EE app to run smoothly within Eclipse, with no reloading of classes and all the bells and whistles is a nightmare, and installing TPTP to profile applications is quite a feat (I haven’t managed yet, because I had to give up at one point or another because of plugin dependencies, dodgy proxy, and instabilities in the atmospheric pressures – and I’m not patient).

Recently, I had therefore to turn back to NetBeans because its profiler doesn’t take a Ph. D and the hacking of your corporate proxy to install: it comes integrated. And that’s one of the things that actually got my attention: there is no plugin version and dependencies nightmare, it’s just there, voilà, a high quality profiler. Like the Subversion integration. It’s there.

So, in the past few months, I have used NetBeans more and more, which is quite surprising, as to me NetBeans still had this “has-been” feel to it. But it appears NetBeans has followed Eclipse trend, and rather than lagging far behind, it has become quite a sustainable alternative. And for some reason, I find code in NB more… readable.

This evening, I had to tick another box in favour of NetBeans: it appears it also have support for Google App Engine. It is located there, and all the details to install it are described in this post. I have tried it, and it’s fairly well done. Ok, the plugin is obviously not as terrific as Eclipse’s, but NB doesn’t benefit from Google’s humungus support, and yet, the plugin is pretty usable from what I can see. I cannot wait to add the Spring library (yes, natively you can add Spring and Hibernate to your project, without much effort), and see whether this is all tying together!!!

This was also few days after discovering the good support for OpenGL:
http://kenai.com/projects/netbeans-opengl-pack/pages/Home.

There are however still some nagging points that prevents me from entirely switching back to NetBeans: the debugger is still somewhat behind, there are some desperately precious functionalities that I cannot find for the life of me, and that are a sore point, like the automatic selection of a file or a class in the Projects or Files views (on Ubuntu, I have to right-click, and go into Select in and then Projects – The shortcut doesn’t work (Ctrl+Shift+1), the Subversion support despite being integrated is still not up to Subclipse level, etc. But it’s definitely worth keeping an eye out for it.

Comment

 
---

17 December 2009

Sébastien

,

SwingWorker

Today I discovered Java 6 SwingWorker. Swing is traditionally a bit tricky to work with when dealing with multi-threading, and though SwingUtilities.invokeLater (or its equivalent EventQueue.invokeLater, the former calling the latter) was good enough, you felt you were a bit on your on your own when it came to implement some task triggered by a button.

SwingWorker provides all the nuts and bolts for performing lengthy tasks, whilst keeping the UI responsive. Here is a simple example of how to use it, directly inspired by Project Euler #7, “find the 10001th prime number” which in turn I remembered thanks to the Javadoc description of SwingWorker (Project Euler always comes very handy when trying to find decent examples).

First, here is the task class that will perform this job, called PrimeNumberTask

import java.util.ArrayList;
import java.util.List;
import java.util.Observer;

import javax.swing.JOptionPane;
import javax.swing.SwingWorker;

public class PrimeNumbersTask extends SwingWorker, Integer> {
    private int numbersToFind;
    private int numbersFound;
    private List primeObservers = new ArrayList();
    
    private int lastPrime;

    PrimeNumbersTask(int numbersToFind) {
	this.numbersToFind = numbersToFind;
    }

    @Override
    protected List doInBackground() throws Exception {
	List primes = new ArrayList();
	int current = 1;
	while (numbersFound < numbersToFind && !isCancelled()) {
	    if (isPrime(current)) {
		numbersFound++;
		primes.add(current);
		notify(current);
	    }

	    if (current < 3) {
		current++;
	    } else {
		current += 2;
	    }
	}

	lastPrime = primes.get(primes.size() - 1);
	return primes;
    }

    public void addObserver(Observer observer) {
	primeObservers.add(observer);
    }

    protected void notify(Integer newPrime) {
	for (Observer o : primeObservers) {
	    o.update(null, newPrime);
	}
    }

    private boolean isPrime(double n) {
	if (n == 1) {
	    return false;
	} else if (n < 4) {
	    return true; // 2 and 3 are prime.
	} else if (n % 2 == 0) {
	    return false;
	} else if (n < 9) {
	    return true; // 4, 6 and 8 already excluded.
	} else if (n % 3 == 0) {
	    return false;
	} else {
	    double r = Math.floor(Math.sqrt(n));
	    double f = 5;
	    while (f <= r) {
		if (n % f == 0) {
		    return false;
		}
		if (n % (f + 2) == 0) {
		    return false;
		}
		f += 6;
	    }
	}

	return true;
    }

    @Override
    protected void done() {
	JOptionPane.showMessageDialog(null, numbersToFind + "st prime is " + lastPrime);
    }
}

In this task, nothing overly exciting. We implement doInBackground, which is our “lengthy task.” This job notifies listeners every time a prime is found: this will be handy for displaying new primes, and updating a JProgressBar.

The frame is a simple Swing UI whose job is to create the interface component (a text area displaying prime numbers, a progress bar, and a button triggering the task), and the action instantiating the task and starting it. It is also responsible for creating the Observers and registering it with the SwingWorker:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.Observable;
import java.util.Observer;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class LongJobFrame extends JFrame {
    public final static int NUMBER_OF_PRIMES = 10001;
    JProgressBar progressBar = new JProgressBar(0, NUMBER_OF_PRIMES);
    JTextArea textArea = new JTextArea();

    public LongJobFrame() {

	JButton startButton = new JButton(new LongJobAction());
	add(BorderLayout.SOUTH, startButton);
	add(BorderLayout.NORTH, progressBar);
	add(BorderLayout.CENTER, new JScrollPane(textArea));

	setSize(600, 450);
	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	setVisible(true);
    }

    class LongJobAction extends AbstractAction {
	public LongJobAction() {
	    putValue(AbstractAction.NAME, "Start");
	}

	@Override
	public void actionPerformed(ActionEvent e) {
	    PrimeNumbersTask task = new PrimeNumbersTask(NUMBER_OF_PRIMES);
	    task.addObserver(new Observer() {
		public void update(Observable o, Object arg) {
		    progressBar.setValue(progressBar.getValue() + 1);
		}
	    });
	    task.addObserver(new Observer() {
		public void update(Observable o, Object arg) {
		    StringBuffer contentBuffer = new StringBuffer();
		    if (textArea.getText().length() > 0) {
			contentBuffer.append(textArea.getText());
			contentBuffer.append(System.getProperty("line.separator"));
		    }
		    contentBuffer.append(arg);
		    textArea.setText(contentBuffer.toString());
		}
	    });

	    task.execute();
	}
    }

    public static void main(String args[]) {
	SwingUtilities.invokeLater(new Runnable() {
	    public void run() {
		new LongJobFrame();
	    }
	});
    }
}

Interestingly enough, you'll notice that I have defined “half” of the Observer pattern, leaving out the Observable. Here it is definitely not useful, as we are maintaining our own list of Observers, saving us the headache of trying to subclass Observable (since our task is already subclassing SwingWorker).

There is also another way to achieve this by using the setProgress method in SwingWorker which triggers a PropertyChangeEvent progress, and all you have to do is register PropertyChangeListener with the Swing worker. The small issue with this is that setProgress only takes a value between 0 and 100 (which would probably be ok for our progress bar), and there is no way of passing a specific object to the listeners like the new found prime, so this means either SwingWorker has to hold a reference to the Swing components to update them (I want to avoid this coupling), or SwingWorker has to hold a instance variable that can be read when the listeners are notified (which has no guarantee of working, as this notification happens asynchronously).

Comment

 
---

15 December 2009

Sébastien

,

ArrayList vs. LinkedList for Stack implementation

This comment made me think: how does a LinkedList fare against an ArrayList for a Stack implementation? Sure, LinkedList should be better for insertion and deletion... But is it? And when does it start to matter (i.e. how many objects)? So I have set up a little benchmark. First, a Stack interface:

public interface Stack<T> {
    public void push(T element);
    public T pop();
    public int size();
}

In this stack, we'll be pushing and popping Elements:

public class Element {
}

Our stack will allow us to pass either an ArrayList or a LinkedList as the implementation:

import java.util.List;

 public class GenericStack<T, U extends List<T>> implements Stack<T> {
    private U list;
    
    public GenericStack(U list) {
    	this.list = list;
    }

    public T pop() {
        if (!list.isEmpty()) {
           return list.remove(0);
        } else throw new IndexOutOfBoundsException("Cannot pop an empty stack");
    }

    public void push(T element) {
        list.add(0, element);
    }

    public int size() {
        return list.size();
    }

The benchmark itself is the following main:

    public static void main(String[] args) {
        int values[] = {1000, 2000, 5000, 10000, 50000, 100000, 500000, 1000000};

        GenericStack<Element, ArrayList<Element>> arrayListStack
                = new GenericStack<Element, ArrayList<Element>>(new ArrayList<Element>());
        GenericStack<Element, LinkedList<Element>> linkedListStack
                = new GenericStack<Element, LinkedList<Element>>(new LinkedList<Element>());

        for (int v = 0; v < values.length; v++) {
            int currentSize = values[v];
            System.out.println("pushing " + currentSize + " elements");
            System.out.println();

            long start = System.currentTimeMillis();
            for (int i = 0; i < currentSize; i++) {
                arrayListStack.push(new Element());
            }
            double time = (System.currentTimeMillis() - start) / (float) currentSize;
            System.out.println("arraylist stack push: " + time);

            start = System.currentTimeMillis();
            for (int i = 0; i < currentSize; i++) {
                linkedListStack.push(new Element());
            }
            time = (System.currentTimeMillis() - start) / (float) currentSize;
            System.out.println("linkedlist stack push: " + time);

            System.out.println("popping " + currentSize + " elements");
            System.out.println();
            for (int i = 0; i < currentSize; i++) {
                arrayListStack.pop();
            }
            time = (System.currentTimeMillis() - start) / (float) currentSize;
            System.out.println("arraylist stack pop: " + time);

            for (int i = 0; i < currentSize; i++) {
                linkedListStack.pop();
            }
            time = (System.currentTimeMillis() - start) / (float) currentSize;
            System.out.println("linkedlist stack pop: " + time);
            System.out.println();
        }
    }

And here are the results (in milliseconds):

pushing 1000 elements

arraylist stack push: 0.0
linkedlist stack push: 0.0

popping 1000 elements

arraylist stack pop: 0.0
linkedlist stack pop: 0.0

pushing 2000 elements

arraylist stack push: 0.0
linkedlist stack push: 0.0

popping 2000 elements

arraylist stack pop: 0.0
linkedlist stack pop: 0.0

pushing 5000 elements

arraylist stack push: 0.0031999999191612005
linkedlist stack push: 0.0

popping 5000 elements

arraylist stack pop: 0.003000000026077032
linkedlist stack pop: 0.003000000026077032

pushing 10000 elements

arraylist stack push: 0.006300000008195639
linkedlist stack push: 0.0

popping 10000 elements

arraylist stack pop: 0.004699999932199717
linkedlist stack pop: 0.004699999932199717

pushing 50000 elements

arraylist stack push: 0.022180000320076942
linkedlist stack push: 0.0

popping 50000 elements

arraylist stack pop: 0.022180000320076942
linkedlist stack pop: 0.022180000320076942

pushing 100000 elements

arraylist stack push: 0.04374999925494194
linkedlist stack push: 3.1999999191612005E-4

popping 100000 elements

arraylist stack pop: 0.04407000169157982
linkedlist stack pop: 0.04407000169157982

pushing 500000 elements

arraylist stack push: 0.2210640013217926
linkedlist stack push: 4.0600000647827983E-4

popping 500000 elements

arraylist stack pop: 0.22146999835968018
linkedlist stack pop: 0.2214999943971634

pushing 1000000 elements

arraylist stack push: 0.4516749978065491
linkedlist stack push: 4.220000118948519E-4

popping 1000000 elements

arraylist stack pop: 0.45311200618743896
linkedlist stack pop: 0.45315900444984436

So a significant difference only appears when pushing 10,000 elements, and after that, it degrades quite dramatically in favour of the LinkedList.

ArrayList that bad?

Now, it appears that we have kind of disadvantaged ArrayList here by choosing the worst case scenario for insertion: inserting at index 0, which means that the implementation will have to enlarge the internal array if needed, shift all the objects by 1, and insert the element at 0.

So let's have more specific implementation where we'll be "pushing" at the end (and therefore "popping" at the end too). Here is our new ArrayListStack:

import java.util.ArrayList;

 public class ArrayListStack<T> implements Stack<T> {
    private ArrayList<T> list = new ArrayList<T>();

    public T pop() {
        if (!list.isEmpty()) {
            return list.remove(list.size() - 1);
        } else throw new IndexOutOfBoundsException("Cannot pop an empty stack");
    }

    public void push(T element) {
        list.add(element);
    }

    public int size() {
        return list.size();
    }
}

To be fair, let's give LinkedList its own implementation, with getFirst() and removeFirst():

import java.util.LinkedList;

 public class LinkedListStack<T> implements Stack<T> {
	private LinkedList<T> list = new LinkedList<T>();

 	public T pop() {
		if (!list.isEmpty()) {
			return list.removeFirst();
		} else throw new IndexOutOfBoundsException("Cannot pop an empty stack");
	}

 	public void push(T element) {
		list.addFirst(element);
	}

 	public int size() {
		return list.size();
	}
}

And now you're in for a good surprise: here are the results!

pushing 1000 elements

arraylist stack push: 0.0
linkedlist stack push: 0.0

popping 1000 elements
arraylist stack pop: 0.0
linkedlist stack pop: 0.0

pushing 2000 elements

arraylist stack push: 0.0
linkedlist stack push: 0.007499999832361937

popping 2000 elements

arraylist stack pop: 0.007499999832361937
linkedlist stack pop: 0.007499999832361937

pushing 5000 elements

arraylist stack push: 0.0
linkedlist stack push: 0.0

popping 5000 elements

arraylist stack pop: 0.0
linkedlist stack pop: 0.0

pushing 10000 elements

arraylist stack push: 0.0
linkedlist stack push: 0.0

popping 10000 elements

arraylist stack pop: 0.0
linkedlist stack pop: 0.0

pushing 50000 elements

arraylist stack push: 0.0
linkedlist stack push: 3.1999999191612005E-4

popping 50000 elements

arraylist stack pop: 3.1999999191612005E-4
linkedlist stack pop: 3.1999999191612005E-4

pushing 100000 elements

arraylist stack push: 1.5999999595806003E-4
linkedlist stack push: 3.100000030826777E-4

popping 100000 elements

arraylist stack pop: 3.100000030826777E-4
linkedlist stack pop: 3.100000030826777E-4

pushing 500000 elements

arraylist stack push: 2.800000074785203E-4
linkedlist stack push: 4.3799998820759356E-4

popping 500000 elements

arraylist stack pop: 4.6999999904073775E-4
linkedlist stack pop: 4.6999999904073775E-4

pushing 1000000 elements

arraylist stack push: 9.40000027185306E-5
linkedlist stack push: 4.3700000969693065E-4

popping 1000000 elements

arraylist stack pop: 4.529999860096723E-4
linkedlist stack pop: 4.6800001291558146E-4

In these results, ArrayList performs better, and after 1,000,000 the difference is actually stunning. And that's even before adding the extra optimization of sizing the list at initialization (thus preventing the overhead of redimensioning the array).

The thing is, adding at the end of an ArrayList will perform better than LinkedList, so this means that for a stack implementation (where you push and pop at the same end), ArrayList is quite a good pick.

Comment [2]

 
---

7 December 2009

Sébastien

,

Using SWT with JRuby

JRuby is a Java implementation of the Ruby programming language. One of the strengths of a Java implementation is that Java libraries can be used within Ruby code, the Ruby way (and that is cool, as we have seen!); the weaknesses are that this means that the code is a lot slower to execute, and similar to what happens with Jython (the Java implementation of Python) the Java implementation lags behind the “official” version. This is obviously to be expected, and in fairness to the JRuby guys, they are pretty reactive!

This post will describe how to use SWT with JRuby. It is written for Ubuntu, but more than likely very similar on other platforms.

Setup

First, get JRuby: I’ll be using 1.4.0 (which was released last month). Install it in a location that I’ll be calling $JRUBY_HOME. Add $JRUBY_HOME/bin into your $PATH so that you can run the jruby command:

sebastien@kilkenny:~$ jruby --version
jruby 1.4.0 (ruby 1.8.7 patchlevel 174) (2009-11-02 69fbfa3) 
(Java HotSpot(TM) Client VM 1.6.0_12) [i386-java]

Get SWT from here (this article will be using SWT 3.5.1 for Linux), and extract swt.jar into $JRUBY_HOME/lib: that’s a quick way of making the jar available to JRuby.

Once everything is set up, we can begin with a very simple example.

First Quick Example

(I have posted the following example as a snippet on dreamincode at the time of writing, it is still awaiting approval)

require 'java'

display = org.eclipse.swt.widgets.Display.new
shell = org.eclipse.swt.widgets.Shell.new(display)
shell.setSize(800, 600)
shell.setText("First Example")

shell.setLayout(org.eclipse.swt.layout.RowLayout.new)
org.eclipse.swt.widgets.Button.new(shell, \
             org.eclipse.swt.SWT::PUSH).setText("Click me!")

shell.open
# Classic SWT stuff
while (!shell.isDisposed) do
  display.sleep unless display.readAndDispatch
end
display.dispose

This opens a nice and simple window:

Typical to JRuby, the first thing we do here is require 'java' to be able to call Java classes from our ruby code. And then, from then on, it is all SWT code: create a Display class, and with this Display, create a new Shell (window), whose size is 800×600. Then set the layout as RowLayout, and add a Button. Make the window visible with open, and the rest of the code is pretty much common SWT code to keep the window open until the application is shut down, at which point, the display is cleared up.

As you can see from above, the only tricky things are:

  • the fully-qualified names of the Java classes have to be provided (we’ll see a way of avoiding this in the next example);
  • static variables have to be accessed with ::

And Now, For a More Advanced Example

The more advanced example will read the RSS feed from weblogism, and fill in some labels, and put items in a table. Ruby provides a neat rss package, and good example of how to use it can be found here.

One of the things you’ll want to look at is the repetition of the Java packages: this is a bit tedious, so we have to find a way of avoiding this. One way is to call include_class to include the Java classes by their name. One trick is to list all the classes of a given package in an array, and to include them with an iterator:

%w(Display Shell Label Table TableColumn TableItem).each do
  |c|
  include_class "org.eclipse.swt.widgets." + c 
end

With this knowledge, I can now give you the example:

require 'java'
require 'open-uri'
require 'rss'

include_class "org.eclipse.swt.SWT"
# Neat little trick to include several classes from the same package.
%w(Display Shell Label Table TableColumn TableItem).each do
    |c|
    include_class "org.eclipse.swt.widgets." + c 
end
%w(GridLayout GridData).each do
    |c|
    include_class "org.eclipse.swt.layout." + c
end

# uppercase variable is constant
FEED_URL = 'http://www.weblogism.com/rss/'

class RssViewer
  attr_reader :shell, :display

  def initialize
    rss = get_messages

    @display = Display.new
    @shell = Shell.new(display)
    @shell.setSize(800, 600)
    @shell.setText("Second Example")

    gridlayout = GridLayout.new
    gridlayout.numColumns = 2
    @shell.setLayout(gridlayout)
    name = Label.new(shell, SWT::NONE)
    name.setText("Name:")
    name.setLayoutData(GridData.new(GridData::VERTICAL_ALIGN_END))
    Label.new(shell, SWT::NONE).setText(rss.channel.title)

    Label.new(shell, SWT::NONE).setText("URL:")
    Label.new(shell, SWT::NONE).setText(rss.channel.link)

    table = Table.new(shell, SWT::MULTI | SWT::BORDER | SWT::FULL_SELECTION)
    table.setLinesVisible(true)
    table.setHeaderVisible(true)

    gridData = GridData.new(GridData::FILL_BOTH)
    gridData.horizontalSpan = 2
    table.setLayoutData(gridData)

    # Set the header of columns.
    columns = %w(Title Date Author)
    columns.each{ |h| TableColumn.new(table, SWT::NONE).setText(h) }
    rss.channel.items.each do 
      |i|
      item = TableItem.new(table, SWT::NONE) 
      item.setText(0, i.title)
      item.setText(1, i.dc_creator)
      item.setText(2, i.date.to_s)
      puts i
    end
    # Each column then needs to be packed to display properly
    for i in 0...columns.size
      table.getColumn(i).pack()
    end

  end

  def show
    @shell.open
    while (!@shell.isDisposed) do
      @display.sleep unless @display.readAndDispatch
    end
    @display.dispose
  end

  def get_messages
    rss_content = ''
    # Read URL
    open(FEED_URL) { |f| rss_content = f.read }
    # and parse.  "false" means "no validation"
    RSS::Parser.parse(rss_content, false)
  end
end

RssViewer.new.show

This simple snippet gives the following window:

Conclusion

The examples above are not that far away from the Java snippets proposed on the SWT web site. This shows how JRuby can be easy to learn if you are already familiar with Java – and you get to play with a few syntactic niceties like the iterators that ruby brings in.

However, it is true that performance can still be an issue on some big apps, but hopefully this will improve in the coming months.

Comment

 
---

24 November 2009

Sébastien

,

That Whole Interfaces and Polymorphism Thing

This post is intended as a follow-up to this discussion in the dreamincode.net Java forum, and this follow-up. I don’t normally get drawn into these sterile debates, but the thing that ticked me off here was that it is all done under the cover of “educating people.” Being wrong is one thing, being wrong and wrapping falsities under layers of apparent knowledge to impart “wisdom” to others whilst being condescending towards other posters is another one.

The whole point of this post is to discuss the incorrect statement that “interfaces in Java cannot define a IS-A relationship.” And explain why this is incorrect.

I have indeed been told that the following is absurd and nonsensical:

// Payable is an interface, and Employee implements Payable
Payable employee = new Employee();

In normal cases, I would have laughed it off, and moved on (or in the case of an interview, I would have thanked the candidate, and parted ways). But there is a pedagogical dimension to all this, so here I am again.

I would certainly dislike being criticized for not giving references, so at the end of this post I have listed a few; however, I’ll be mostly speaking about my own experience as a Java developer, so yeah, this will be biased big time.

As said before, I truly believe that the statement “using Java interfaces for polymorphism is absurd” is symptomatic of 3 things:

  • The misunderstanding of what Java interfaces are all about,
  • The scorn the implements keyword is treated with,
  • The immoderate idolization some developers devote to inheritance.

Interfaces in Java

The Spec

Let’s look at the Java Language spec1 has to say about interfaces:

An interface declaration introduces a new reference type whose members are classes, interfaces, constants and abstract methods. This type has no implementation, but otherwise unrelated classes can implement it by providing implementations for its abstract methods. (…) A variable whose declared type is an interface type may have as its value a reference to any instance of a class which implements the specified interface.

This means that (i) an interface is a type (and we could actually stop this post here), and (ii) this is totally valid stuff:

Payable employee = new Employee();

if Employee implements Payable.

(This is also valid, mind you:

public interface Payable {
    long baseSalary = 10000;
    public void pay();
}
public class Employee implements Payable {
    public void pay() {
        System.out.println("pay Employee " + f);
    }

    public static void main(String[] args) {
        Payable p = new Employee();
        p.pay();
    }
}

but that’s irrelevant.)

However, the fact it is valid code has never been in doubt, but rather the intent was. Right so, let’s carry on.

Interface as a Type

To quote the Java Tutorial2, in the Using Interfaces as Types ([sarcasm]wow, how can these Sun people use such a nonsensical title?[/sarcasm]) section:

When they [“relatable” objects] implement Relatable, they can be of both their own class (or superclass) type and a Relatable type. This gives them some of the advantages of multiple inheritance, where they can have behavior from both a superclass and an interface.

The interesting thing here is the word “behaviour.” The interface brings behaviour to a class; we’ll see what this means in terms of object-oriented programming. We will also see that you can’t just go and remove an interface to prove a heavily-flawed demonstrative point.

instanceof

instanceof is the type comparison operator in Java. In the case of an interface, this is indeed valid:

new Employee() instanceof Payable

and returns true.

According to the Java Language spec1 (See here):

It is a compile-time error if the ReferenceType mentioned after the instanceof operator does not denote a reifiable type (§4.7).

Which does indicate, if there was any doubt about it, that interfaces are reifiable types.

The Serializable case

To finish with this Java interface analysis, let’s look at the Serializable interface. Wait. It’s empty, what is there to look at? Precisely. What is an empty interface supposed to bring to the table? What is the point of marking classes as Serializable when there is no method to implement? The point is to give an object the Serializable type to use polymorphism when invoking the serialization mechanisms. In practice, this is done through the instanceof keyword, but if the object is not of type Serializable, the code throws a NotSerializableException.

Interfaces and OOP

Apparently, it was not just a Java problem anymore. The big guns had to be taken out, and OOP was invoked in the grand pursuit of Java interfaces slurring.

First of all, let’s make something clear: Java interfaces are not a bijection to interfaces in the OOP sense. We have on one hand a programming language feature, and on the other hand an OOP concept. It is not just that the 2 sets mismatch: they are not on the same plane at all.

Interface vs. Implementation

When it comes to design, Design Pattern3 is the unavoidable reference. The section called Class versus Interface Inheritance discusses at length the importance of programming to an interface.

It’s important to understand the difference between an object’s class and its type.

An object’s class defines how the object is implemented. The class defines the object’s internal state and the implementation of its operations. In contrast, an object’s type only refers to its interface—the set of requests to which it can respond. An object can have many types, and objects of different classes can have the same type.

In this chapter appears the principle that any design-savvy developer knows: “Program to an interface, not an implementation“.

Don’t declare variables to be instances of particular concrete classes. Instead, commit only to an interface defined by an abstract class.

What do they mean by “programming to an interface”? It means that instead of programming around a specific implementation, it is preferable to pass around an interface (in the OOP sense, not necessarily Java interface) and make sure the behaviour is decided at runtime.

The reason is quite straightforward: you don’t want to be tied to a particular implementation. The classic textbook example of this is the Collection interface. Beginners usually code collections like this:

ArrayList words = new ArrayList();

All the subsequent method calls then would take an ArrayList<String> as a parameter.

The problem with this approach is that if one day, it is decided to switch to a different implementation (to get a synchronized collection, or to have the words sorted directly with TreeSet, or to switch to the kick-ass Google Collections library), you’ll have to go through lots of code and do the change. Ideally, you want to avoid this at all costs. But by tying your code to an implementation, you leave the door open to subsequent changes – and developers get annoyed with interface changes (interface as in API, obviously). “WTF? This method was requiring an ArrayList last week, and now it requires a TreeSet?!”

(Where I work, changing an interface potentially means that client jars to Web services have to be redeployed, and the 2 or 3 major in-house applications have to be re-released to include the change. That’s usually a messy affair, and always a bit risky, so you usually avoid changing the exposed services)

On the other hand, if you write:

Collection words = new ArrayList();

you can hide the actual implementation, and parse your elements with Iterator without worrying about potential changes.

The same way you want to program to interface to avoid tight coupling with a specific implementation, you also want to avoid inheriting implementation, as changes to the implementation can have adverse effect on all the subclasses.

Avoid coupling, favour composition over inheritance, program to interfaces, not implementations, that’s the OO principles that any developer would find when opening a decent OOP book. Interestingly enough, this has been discussed at length elsewhere.

Questions?

But if I remove the interface, it is working still. You’ve lost nothing.

My oh my. Again, any candidate stating this in an interview would be out of the door in the next minute.

For this one, we’ll need an example. Let’s say, hey, that Payable one.

public interface Payable {
  public void pay();
}

public class Employee implements Payable {
  public void pay() {
    System.out.println("pay Employee");
  }
}

public class Contractor implements Payable {
  public void pay() {
    System.out.println("pay Contractor");
  }
}

public static void main(String[] args) {
  Employee e1 = new Employee();
  e1.pay();

  Payable e2 = new Employee();
  e2.pay();

  Payable e3 = new Contractor();
  e3.pay();

  Contractor e4 = new Contractor();
  e4.pay();
}

This prints out:

pay Employee
pay Employee
pay Contractor
pay Contractor

Now remove Payable. Not only they did lose something, but they lost something huge: they lost their type! All these methods relying on the interface would fail:

public void hire(Payable p) {
// ...
}

Contractor and Employee also lost their relationship to each other. You just can’t go removing stuff from your design without removing the precious information it was bringing in the first place. That would be just as bad as removing Payable from below:

public class Payable {
  public void pay() {
    System.out.println("pay Payable");
  }
}

public class Employee extends Payable {
  public void pay() {
    System.out.println("pay Employee");
  }
}

public class Contractor extends Payable {
  public void pay() {
    System.out.println("pay Contractor");
  }
}

Similar to Payable as an interface, Payable as a class “doesn’t do anything”, so let’s go and remove it; but again here, you lose a vital thing: the fact that Employee and Contractor are Payable. Everyone can see this is silly, and yet this is exactly the same thing with interfaces.

One could argue that Payable could have defined other behaviour not overridden by the subclasses, but here it is not the case: it happens in real life too. Usually, you’d make this class abstract, but it’s not always in your control: Payable could be a third-party class you’re trying to adapt (as in, the Adapter design pattern) into your own application.

The confirmation to this is the Serializable example mentioned earlier which must be the epitome of the “useless” interface (it doesn’t define any method): remove it, and it makes a world of difference.

Hey, but Payable is an interface name, it wouldn’t be a class name

This is just a naming convention. Some people suffix their interfaces with -able, some prefix it with I (like IComponent). The problem with this naming convention is that it has contributed to the under-component status interfaces are suffering from. More and more you see this trend being reversed to put the onus back onto the interface (especially with the coming of Spring), and interfaces have the component name, and implementations have suffixed with Impl:

public interface Employee {
  public void pay();
}

public class EmployeeImpl implements Employee {
  public void pay() {
    System.out.println("pay EmployeeImpl");
  }
}

This is quite some psychological leap! What this means is that the focus is now on the interface, and that the implementation comes second. Just like it should.

You seem to be confusing abstract classes and interfaces. Are you?

No. I put them in the same bag because they both are useful to define an interface in the OOP sense. From a technical point of view, they are not the same, and they have their own pros and cons. Depending on the situation, you’ll want to favour one or the other, bearing in mind that if you inherit an abstract class, you cannot inherit anything else, but you can provide a default implementation, whereas you can implement lots of different interfaces with their own hierarchy, but face to change all implementing classes if you change anything. Choosing an abstract class over an interface makes also a strong design point (since indeed you cannot inherit anything else); however, this doesn’t mean the type provided by the interfaces is not also important, or should be discarded.

Conclusion

Interfaces have not been defined in the Java language just to “ensure some methods are implemented in the class that implements them”, or as a “CAN-DO” relationship. This view is far too simplistic as we have seen above, and there is no doubt (at least in my mind) that Java interfaces do provide a “IS-A” relationship, and that it is actually their whole raison d‘être. Unfortunately, failing to understand this means you cannot possible leverage technologies such as Spring, mocking, Java proxies, etc. but also shows a fairly questionable knowledge of Java itself, as everything in the language is based around this: serialization, collections, sorting, listeners, EJBs, etc.

1 The Java Language Specification, http://java.sun.com/docs/books/jls/

2 Learning the Java Language, http://java.sun.com/docs/books/tutorial/java/IandI/interfaceAsType.html

3 Design Patterns: Elements of Reusable Object-Oriented Software, Erich Gamma et al.

4 Code Complete, Steve McConnell.

Comment [1]

 
---

← Older