The Appendable interface (ctd)

The Appendable interface allows us to write methods that will append string data to a variety of Java classes, including StringBuffer, PrintStream, Writer etc. These objects aren't subclasses of a common parent. Indeed, giving them a common parent probably wouldn't have been convenient. So instead, the API designers (as of Java 5) provided an interface which defines a couple of methods common to these and other classes. The beginning of the definition of Appendable looks as follows:

public interface Appendable {
  Appendable append(CharSequence csq) throws IOException;
  ...
}

What this basically says is: "anything that is an Appendable must have an append() method". The append() method is declared as taking a CharSequence (itself an interface: for now, you can pretend it's a String). (It also returns an Appendable: the idea is that the object being called on returns itself, to allow method chaining.) But note that the interface definition doesn't contain any actual code inside the method: it just says "a class that is Appendable will implement append() some way or other".

Then, to make a particular class Appendable, we (or in this case, the API designers) declare that it implements Appendable, and then add a definition of the appropriate method(s). (In fact, Appendable has a couple of other methods that we won't worry about here.) So the Writer class looks something as follows1:

public abstract class Writer implements Appendable {
  ...
  public Writer append(CharSequence csq) throws IOException {
    if (csq == null)
      write("null");
    else
      write(csq.toString());
    return this;
  }
}

Various other classes similarly implement Appendable. Note that inside Writer's append() method, a call is made to write() which is specific to Writer. In the append() implementation of, say, PrintStream, a different method is called as appropriate.

So now, coming back to our original appendData() method, we can declare it as taking any old Appendable:

public void appendData(Appendable a) throws IOException {
  a.append(...);
}

Now that this method takes Appendable, it can be called with any type of object that implements this method: a StringBuilder, StringBuffer, CharBuffer, PrintStream, PrintWriter etc. In other words:

Exceptions

Methods of interfaces can be declared as throwing exceptions. In the Appendable interface definition above, you'll see that the append() method can actually throw an exception. So we now have to deal with that exception ourselves (in this case by simply throwing it up). In fact, a specific implementation is allowed to declare that it doesn't throw the given exception (or that it throws a smaller subset of exceptions), but that doesn't help us in the general case where the whole point is that we don't know or care which specific type of object we'll be dealing with.


1. Writer actually implements some other interfaces as well as Appendable.


If you enjoy this Java programming article, please share with friends and colleagues. Follow the author on Twitter for the latest news and rants.

Editorial page content written by Neil Coffey. Copyright © Javamex UK 2021. All rights reserved.