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 cap
able to do such things. I mean I guess it isn’t a bad interface name if an interface is meant to do such action.
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.
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.
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 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
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.
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 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:
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:
instead of traditional plain java:
You can apply similar code to Comparable object as well.
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.