Java Interfaces

-ables in Java


28 Nov 2016 View Comments
#java #computer #interface #serializable #cloneable #iterable #callable #comparable

Java interfaces: commonly used -ables in Java

There are a couple of interfaces which ends with -able in their name. I thought I would show you most of them here and explain their usage. Do not be mistaken. Names that ends with able is not any defined naming convention for Java interfaces. It is just denoting that implementing this interface makes the class capable to do such things. I mean I guess it isn’t a bad interface name if an interface is meant to do such action.

Serializable

This interface is quite interesting. This is a famous for a Marker Interface in Java. Using implements Serializable, it is used to indicate something to compiler or JVM. When JVM sees this from a class, it does a special activity, i.e. serializes the object in this case. Serialization is a quite complicated beast and should not be taken lightly when you use it. Once an object is defined to be a serializable object, implementation flexibility decreases significantly. A small change to the serializable object may have a bad impact on deserialization process. Also, serializable object may introduce bugs or create security holes easy. You should appropriately assign variables with a transient field. There are so many variables you need to think about. It is mostly a bad idea to ever use serialization with inheritance relationship because of the similar reasons as I described above. Anyways, avoid using this interfaces if you can.

Cloneable

Here is another marker interface which tells the JVM to do a special behavior. The special behavior, in this case, is to clone an object. When you make the object cloneable by implements Cloneable, you are given an option to override clone. However, as this is a marker interface, you will not be given with properly functioning clone function. You need to pay extra attention when you are defining the clone function. Make sure the super.clone is covered in non-final classes. It is probably better to provide an optional behavior for copying an object the way you wishes to. One clone function that clones an object to another is not easy. A fine way of copying an object is to provide a copy constructor or even copy static factory. Instead of defining you own clone function, use library out there that does deep copying such as Apache Commons, SerializeUtils. Also, for a clone function, you will need to think about synchronization as well. The same is true for copy constructor. So it could be that while you are reading the first value in one thread the second value may be changed by another thread. Then, after all, you have a “copied” object in an inconsistent state.

Iterable

Iterables basically allow for iteration over any Collection. This is possible via implements Iterable<Object>. This enforces the user to override an iterator method which will be used to iterate through the item. For most of Java Collections data structures such as a List or a Set, you don’t need iterator defined. You can just use the default iterator from the Collections library. If not, you can use both implements Iterable<Object>, Iterator<Object> and define your custom definitions of how iteration is going to behave, in terms of next(), hasNext() etc. Iterator and Iterable are both embedded inside of collections library. A Collection is iterable, it is a super interface to Collection. If you need to play around with Iterables. Guava provides a nice interface which has a couple of options. Please have a look. Iterables are what allows foreach to happen for Java Collection.

Callable / Runnable

Callable interface is very similar to the Runnable interface. They are both designed to represent a task, which can be executed by Threads. However, with Callable, you can return a result performed by call() method which was the limitations with the Runnable interface. Another difference in between them is that Callable can return a checked exception. This seems to be a small thing, but it is really powerful when you categorize the right checked exception inside call() method. Callable is also fairly recent compared to Runnable. Callable was introduced in Java 5. The ways that initiate Callable is quite different from Runnable. With Runnable, you can simply create objects that implements Runnable and define run() method for a thread task. Then you could use Thread class to initialize Thread with this Runnable. With Callable, the easiest way is to use the Future. There are many examples online. You could also use Runnable Thread to run a thread that calls the Callable, basically call() inside run(). Future is useful when you expect a return value from the call. Future has a method called .get() where you can retrieve the value out of Callable object.

Closeablea / AutoCloseable

This interface is used for closing a source or destination of data that can be closed. The close method is invoked to release resources that the object is holding (such as open files). The Closeable interface extends the AutoCloseable interface. The close method of the Closeable interface throws exceptions of type IOException while the close method of the AutoCloseable interface throws exceptions of type Exception. Consequently, subclasses of the AutoCloseable interface can override this behavior of the close method to throw specialized exceptions, such as IOException, or no exception at all. This interface is used throughout java built in classes that normally requires a close operation such as BufferedInputStream, BufferedOutputStream, FileReader, FileWriter, InputStream, OutputStream, Reader, Writer, etc. You can of course implements Closeable and similar behavior. My suggestion would be to apply on resources that require a close action, whether it is reading or writing.

Comparable / Comparator

Comparable interface is so much useful for sorting any kind of data. It is similar in character to Object’s equals method, except it’s not declared in Object. It permits order comparisons by adding simple equality comparisons. Comparator is another interface which does a very similar thing. Check this website to see the differences. You should consider implementing comparables. Keeping a default ordering on an object is useful when coding especially in testing. Arrays.sort(a) works with sorting objects that implements Comparable. Similarly, Collections.sort(a) for sorting a collection. I personally use comparator quite often, because you can use comparator explicitly like Collections.sort(a, new NaturalOrdering()) and use a generic template like below:

class NaturalComparator<T extends Comparable<T>> implements Comparator<T> {
  @Override
  public int compare(T a, T b) {
    return a.compareTo(b);
  }
}

This is a basic Sort just use basic Comparable defined in a and b. There is Guava’s ComparisonChain which is much useful in Comparator. You can do something like below:

private static class EventComparator implements Comparator<Event> {
    @Override
    public int compare(final Event a, final Event b) {
        return ComparisonChain.start().compare(a.getName(), b.getName())
                .compare(a.getLocation(), b.getLocation()).result();
    }
}

instead of traditional plain java:

private static class EventComparator implements Comparator<Event> {
    @Override
    public int compare(final Event a, final Event b) {
        int result = 0;
        
        result = a.getName() != null ? a.getName().compare(b.getName()) : result;
        result = result == 0 ? a.getLocation().compareTo(b.getLocation()) : result;
        
        return result;
    }
}

You can apply similar code to Comparable object as well.

Conclusion

There are other -able interfaces than what I described above. The examples I provided above are probably most commonly used -able interfaces in Java. You can implement multiple interfaces to accommodate the need for your class. For example, if your class needs to keep the ordering and needs to be serialized. Once you have an item that can be serialized. I would use Apache Commons SerializationUtils to perform necessary work.

Share this post

Me

I am a passionate programmer working in Vancouver. I strongly believe in art of algorithms and together with it to write clean and efficient software to build awesome products. If you would like to connect with me, choose one from below options :) You can also send me an email at