Muhammad Khojaye is an experienced consultant who has worked on both large scale Agile development projects for top financial clients and public sector innovative research and development projects. In his spare time, Muhammad likes to work on independent open source programs. Muhammad is a DZone MVB and is not an employee of DZone and has posted 13 posts at DZone. You can read more from them at their website. View Full User Profile

Are Marker Interfaces Dead?

02.01.2010
| 13330 views |
  • submit to reddit

Marker Interfaces and Annotations

In earlier versions of Java, Marker Interfaces were the only way to declare metadata about a class. With the advent of annotation in Java 5, it is consider that marker interfaces have now no place. They can be completely replaced by Annotations, which allow for a very flexible metadata capability. Everything that can be done with marker interfaces can be done instead with annotations. In fact, it's now recommended that the marker interface pattern should not be used anymore. Annotations can have parameters of various kinds, and they're much more flexible. We can also see that the examples used in Sun API’s are rather old and that no new ones have been added since after introduce of Annotation. In this post, we will see whether Marker Interfaces can still be used for any reasons.

Marker Interface

A marker interface is an interface with no method declarations. They just tell the compiler that the objects of the classes implementing the interfaces with no defined methods need to be treated differently. These Marker interfaces are used by other code to test for permission to do something.

Some well-known examples are

java.io.Serializable - object implement it can be serialized using ObjectOutputStream.
java.lang.Clonable - objects clone method may be called
java.util.RandomAccess- support fast (generally constant time) random access

They are also known as tag interfaces since they tag all the derived classes into a category based on their purpose

Interface and Marker Interfaces

Interface in general defines a contract. They represent a public commitment and when implement form a contract between the class and the outside world. On the other hand, an empty interface does not define any members, and as such, does not define a contract that can be implemented.

Normally, when a class implements an interface, it tells something about the instances of the class.  It represent an "is a" relationship that exist in inheritance. For example, when a class implements List, then object is a List.

With marker interfaces, this inheritance mechanism usually does not obey. For example, if class implements the marker interface Serializable, then instead of saying that the object is a Serializable, we say that the object has a property i.e. it is Serializable.

Should Avoid Marker Interfaces?

One common problem occurs while using marker interfaces is that when a class implements them, all of its subclasses inherit them as well.  Since you cannot unimplement an interface in Java, therefore a subclass that does not want to treat differently will still be marked as Marker. For example, Foo implements Serializable, any subclass Bar etc does too as well.

Moreover, there are places in the Sun API’s where such interfaces have been used for messy and varying purposes. Consider Cloneable  Marker Interface. If the operation is not supported by an object, it can throw an exception when such operation is attempted, like Collection.remove does when the collection does not support the remove operation (eg, unmodifiable collection) but a class claiming to implement Cloneable and throwing CloneNotSupportedException from the clone() method wouldn't be a very friendly thing to do.

Many developers consider it as broken interface. Ken Arnold and Bill Venners also discussed it in Java Design Issues. As Ken Arnold said,

If I were to be God at this point, and many people are probably glad I am not, I would say deprecate Cloneable and have a Copyable, because Cloneable has problems. Besides the fact that it's misspelled, Cloneable doesn't contain the clone method. That means you can't test if something is an instance of Cloneable, cast it to Cloneable, and invoke clone. You have to use reflection again, which is awful. That is only one problem, but one I'd certainly solve.

 

 Sun has also reported it as Bug which can refer at http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4098033

Are Marker Interfaces end?

We usually hear that Marker Interface is now obsolete and it has no place. But, there are situations where they can be handy over using annotations.

Annotations have to be checked at runtime using reflection. Empty interfaces can be checked at compile-time using the type-system in the compiler. Compile-time checking can be one of convincing reason to use such interfaces.

Consider the example below,

@interface
HasTag {
}

@HasTag
public class ClasswithTag {
}

public void performAction(Object obj){
if (!obj.getClass().isAnnotationPresent(HasTag.class)) {
throw new IllegalArgumentException("cannot perform action...");
}
else {
//do stuff as require
}
}

One problem with this approach is that the check for the custom attribute can occur only at runtime. Sometimes, it is very important that the check for the marker be done at compile-time. Let me refine the above example to use Marker.

interface HasTag {
}

public class ClassWithTag implements HasTag {
}

public void performAction(HasTag ct){
//do stuff as require
}

Similarly, in the case of the Serializable marker interface, the ObjectOutputStream.write(Object) method would fail at runtime if its argument does not implement the Interface which would not be the case, if ObjectOutputStream had a writeObject(Serializable) method instead.

Marker Interfaces can also be well integrated in javadoc where one can promptly see who implements <marker interface> or not by just look it up and see the list of implementing classes.

Moreover, Joshua in Effective Java also recommends using Marker interface to define type which can result in the very real benefit of compile-time type checking.

- See more at: http://muhammadkhojaye.blogspot.com/2010/02/are-marker-interfaces-dead.html 

Published at DZone with permission of Muhammad Khojaye, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Slim Ouertani replied on Mon, 2010/02/01 - 8:28am

Great post.

I agree no place to Marker interface. Scala implements @serialisable for example ;)

Lincoln Baxter replied on Mon, 2010/02/01 - 10:44am

I don't think that removing interfaces from sub-classes should be legal. That would violate the Liskov Substitution Principle, which as far as I know, is generally well understood to be a good thing :) Subclasses must provide the same behavior as their supers, so un-implementing an interface would violate that contract. In a strongly typed language, that can mean death. Then we'd have lots of: java.lang.MethodNotFoundException popping up everywhere ;)

Alex Miller replied on Mon, 2010/02/01 - 11:48am

Nice article. I'm not saying this is a good idea... but you could probably get the effect of compile-time checking with an annotation by using the APT to plugin a checker at compile-time. The JSR 308 stuff extends this capability quite a bit as well. This of course is wildly more complex than using a marker interface. :)

Peter Lawrey replied on Sat, 2010/02/06 - 5:49am

I though marker interfaces to be dead, but uses for them pop up again. 

 

We use marker interfaces in our OSGI container.  This is because it wires components together based on interfaces. Some of those interfaces have no manditory methods.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.