Java – Marker Annotation vs Marker Interface

annotationsinterfacejava

While reading about Marker interfaces I stumbled upon the following site : Item 37: Use marker interfaces to define types

Here, according to Joshua Bloch there are two advantages of Marker interfaces over the Marker annotations.

  1. Marker interfaces define a type that is implemented by instances of
    the marked class; marker annotations do not. The existence of this
    type allows you to catch errors at compile time that you couldn’t
    catch until runtime if you used a marker annotation.

  2. Another advantage of marker interfaces over marker annotations is
    that they can be targeted more precisely. If an annotation type is
    declared with target ElementType.TYPE, it can be applied to any
    class or interface. Suppose you have a marker that is applicable
    only to implementations of a particular interface. If you define it
    as a marker interface, you can have it extend the sole interface to
    which it is applicable, guaranteeing that all marked types are also
    subtypes of the sole interface to which it is applicable.

OK, First point is understood but I'm not sure if I understand the 2nd point correctly:

If an annotation type is declared with target ElementType.TYPE, it can be applied to any class or interface.

Likewise, if I have a marker interface then that too can be applied to any class or interface. Isn't it saying the same thing about marker annotations and marker interfaces? How can a marker interface be targeted more precisely?

The 2nd point also mentions that:

you can have [the Marker Interface] extend the sole interface to which it is applicable, guaranteeing that all marked types are also subtypes of the sole interface to which it is applicable.

Can't you also achieve this with annotations, by using the @Inherited meta-annotation?

Best Answer

How can a marker interface be targeted more precisely?

You are correct that both could be applied to any type. By "targeted more precisely" the author means that you can add additional restrictions to which specific types a marker interface can be applied to. It is not possible to add the same precise restrictions to annotations: If an annotation is restricted to ElementType.TYPE, then it can always be applied to all types.

The other part of the 2nd point goes into details how you can add those restrictions. If you have a marker interface, you can let it extend another interface (which the author calls the sole interface) like this:

interface Marker extends Foo { }

The marker can now only be applied to types which implement Foo.

Can't you also achieve this with annotations, by using the @Inherited meta-annotation?

No, the @Inherited meta-annotation only means that any subtype of an annotated class will be treated as if it also had the same annotation. It does not impose any restrictions to which types the annotation can be applied to.