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.
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.
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?
It seems annotation is a better choice than the marker interface as the same effect can be achieved by the annotations. It can mark variables, methods, and/or classes. It can mark any class specifically, or via inheritance. A marker interface will mark all subclasses of the marked class.
What is a Marker Annotation? Marker annotations are special annotations in Java that do not contain any members or data. As marker interfaces do not contain any members, just declaring the annotation in your code is sufficient for it to influence the output in whatever terms you want.
A marker interface is an interface that has no methods or constants inside it. It provides run-time type information about objects, so the compiler and JVM have additional information about the object. A marker interface is also called a tagging interface.
A marker interface is an interface declaring no methods, a functional interface is one with only one abstract method.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With