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?
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.
Related
In a recent interview I was asked the question that "how can we say that in java8 the functional interfaces are similar to marker interfaces".
I was not able to answer this question.
But I think marker does not even have any methods while functional interface has to have one method to be overridden.
Can someone help me understand this whether this is a valid argument in some context maybe or the question itself is wrong?
Typically, a marker interface is an interface that alone by its presence has some sort of effect. In other words: some sort of framework will use instanceof or maybe reflection to identify situations where some object or class implements that marker interface, to then do something based on that information.
And I agree to your understanding: calling a specific method of that interface isn't part of that concept "marker interface", at least in my book.
And beyond my book, that seems to be a well known convention: marker interfaces do not declare a method, see here or there. Both these sources emphasize: a marker interface doesn't have methods or constants.
Therefore I agree with your stance: Function and other interfaces in that package aren't marker interfaces in that strict sense.
On the other hand, I doubt that you will find an "official" definition of that term (for example in the Java Language spec). And when there is no official standard, people are free to make up the "meaning" of words.
So maybe your interviewer decided that "being a SAM" interface is somehow a "marker", too. And I am pretty sure you can't sue him for his opinion.
Some more details :
Functional interface:
From Java 8 Docs
public #interface FunctionalInterface
An informative annotation type used to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification. Conceptually, a functional interface has exactly one abstract method. Since default methods have an implementation, they are not abstract. If an interface declares an abstract method overriding one of the public methods of java.lang.Object, that also does not count toward the interface's abstract method count since any implementation of the interface will have an implementation from java.lang.Object or elsewhere.
Note that instances of functional interfaces can be created with lambda expressions, method references, or constructor references.
If a type is annotated with this annotation type, compilers are required to generate an error message unless:
The type is an interface type and not an annotation type, enum, or class.
The annotated type satisfies the requirements of a functional interface.
However, the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a FunctionalInterface annotation is present on the interface declaration.
May be your interviewer want info about SAM.
So Functional interface a marker interface at all.
In order for a functional interface to compile, besides annotating the interface with #FunctionalInterface you have to declare a single abstract method as part of the interface.
If you try to compile an interface annotated with #FunctionalInterface but without an abstract method you'll get:
FunctionalInterfaceAttempt.java:1: error: Unexpected #FunctionalInterface annotation
#FunctionalInterface
^
JavaJava is not a functional interface
no abstract method found in interface JavaJava
1 error
and if you try to compile the same intarface with multiple abstract methods you'll get:
JavaJava.java:1: error: Unexpected #FunctionalInterface annotation
#FunctionalInterface
^
JavaJava is not a functional interface
multiple non-overriding abstract methods found in interface JavaJava
1 error
I think that such behaviour does not fit the definition of a marker interface.
I am facing difficulties to decide between using a marker interface or an empty abstract class.
I have two classes BrokerResponse and Notification, which have no structural similarity. The only thing connecting them is the need to be subscribable for.
void register(Receivable receivable, BrokerObserver observer)
I somehow dislike using a Marker Interface, because it violates the basic definition of an Interface. On the other hand using an abstract super class would make me as uncomfortable, because both classes have no relationship with one another.
What is the generally preferable approach in this scenario and why?
Edit 1
I forgot to mention, that BrokerResponse is an abstract class itself, that has several subclasses to determine the respective type.
Abstract class vs. marker interface:
There is nothing wrong with marker interface and there are some use cases for it. Choosing between those two, marker interface has more flexibility.
If you do want to define a type, do use an interface.
An abstract class’s purpose is to provide an appropriate superclass from which other classes can inherit and thus share a common design - your classes don't have common design and nothing to share. Moreover you will stick both of them to some restricted design and will be not so flexible if you will need to add a real different parents to them in the future.
List of use-cases for abstract class:
Share code among several closely related classes.
Classes that extend your abstract class have many common methods or
fields or require access modifiers other than public (such as
protected and private).
Declare non-static or non-final fields what enables you to define
methods that can access and modify the state of the object to which
they belong.
Use-cases for interface:
Unrelated classes would implement your interface.
Specify the behavior of a particular data type, without concerning
who implements its behavior.
Advantage of multiple inheritances.
All listed arguments are for the usage of interface. Since BrokerResponse is abstract itself and has it's own hierarchy, making the fact that those classes don't have something in common more stronger.
As alternative you can use marker annotation. I would consider to stick one of those two approaches instead of Abstract Class.
Marker interface vs. marker annotation:
According to Joshua Bloch's 'Effective java':
Marker interfaces have two advantages over marker annotations. First
and foremost, 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.
When should you use a marker annotation?
you must use an annotation if the marker applies to any program
element other than a class or interface, as only classes and
interfaces can be made to implement or extend an interface.
When should you use a marker interface?
Ask yourself the question, Might I want to write one or more methods
that accept only objects that have this marking? If so, you should use
a marker interface in preference to an annotation. This will make it possible
for you to use the interface as a parameter type for the methods in
question, which will result in the very real benefit of compile-time
type checking.
Summary:
If you want to define a type that does not have any new methods
associated with it, a marker interface is the way to go.
If you want to mark program elements other than classes and
interfaces, to allow for the possibility of adding more information to
the marker in the future, or to fit the marker into a framework that
already makes heavy use of annotation types, then a marker annotation
is the correct choice.
Using empty abstract class does not make any sense in this case as there is no multiple inheritance in Java.
Making you class implement some marker interface does not change you class hierarchy, it just marks your class with some additional metadata.
Image the case when your class which already is marked as Subscribable should also be for example Writable. If you use empty abstract class you will need to redesign the entire hierarchy. With marker interface it is just as easy as to add Writable to list of implementations.
How about annotating them? You got your answer that using a mark interface is the way to go here if you would have to choose, but using an annotation depending on what you might need to do would be much cleaner.
The fact that you say you need to make them somehow "the same" talks about an instanceof call and doing something based on that. The same thing could be achieved via isAnnotationPresent or the like.
But if you add a marker interface, how about making it not a marker interface - only in case you have a finite number of classes you need to test against? Something along the lines of MyInterface {boolean isSubscribable();}
How is the Comparable interface is marker interface, even though it defines a compareTo() method?
Please explain detail.
A marker interface is just a design pattern. So even if you read around "X is a marker interface" this doesn't really mean anything apart from "X is an interface with no methods declared".
Since Comparable<T> has one method then it is not used as a marker interface.
A marker interface is useful when you want to attach data to a type to be able to use this data in specific situations, this is not the case of Comparable, which is used to provide an effective interface.
I don't even think that the definition of marker interface is used in javadoc to describe empty intefaces such as Serializable (not sure about it though).
It is not a marker interface. Marker interface in Java for e.g. Serializable, Clonnable and Remote are used to indicate something to compiler or JVM; indicate a flag to compiler.
Quoting Wikipedia on Marker interface pattern (emphasis mine):
[...] class implements a marker interface, and methods that interact with instances of that class test for the existence of the interface. Whereas a typical interface specifies functionality (in the form of method declarations) that an implementing class must support, a marker interface need not do so. The mere presence of such an interface indicates specific behavior on the part of the implementing class. Hybrid interfaces, which both act as markers and specify required methods, are possible but may prove confusing if improperly used.
That being said Comparable<T> can be called a marker interface, but it's confusing and I've never heard this before.
I can't imagine a class testing whether some object implements Comparable<T> without actually down-casting and calling compareTo().
Is there a list of standard marker interfaces in Java? I've read (in some Java book) that marker interfaces do not have any methods to implement , however when I did a google search - there are certain answers which specify that marker interfaces can indeed have methods. If that is the case then I think there is no difference between a regular interface and marker interface - would it be possible to clear my confusion :)
There is indeed no technical difference between "standard" and "marker" interfaces.
Normally you define an interface to define methods that implementing classes should have. If you don't specify any methods you call the interface a marker interface, since if only marks the class as having some property.
Examples of that are Serializable, Cloneable etc. Those interfaces don't define any methods themselves, but by convention and specification you have to option to implement some special methods related to them, e.g. some serializaton methods related to Serializable. The core Java libraries would then use reflection to check whether those methods exist if a marker interface is implemented.
There is at least one: Serializable. I personally do not remember others.
The technique of defining ta interfaces is old and almost obsolete since java 1.5 when annotations were introduced, so you can use annotation to "tag" class instead of empty interface.
Marker interfaces are used as a tag to inform a message to the java compiler so that it can add special behaviour to the class implementing it and they do not have any method declarations.
The need for marker interface no longer exists since the introduction of the java annotation feature.
Better use the more powerful java annotations than the marker interface.
Some examples of marker interfaces:
java.lang.Cloneable
java.io.Serializable
java.rmi.Remote
java.util.EventListener
SigleThreadModel is also marker interface - ( I know it's deprecated now, but just for example I'm putting it's name here)
See more about it here
An interface is called a marker interface when it is provided as a handle by Java interpreter to mark a class so that it can provide special behaviour to it at runtime and they do not have any method declarations
Java Marker Interface Examples
java.lang.Cloneable
java.io.Serializable
java.util.EventListener
I don't know that there is a list of marker interfaces in the standard Java api. Whether marker interfaces can specify methods is explained well, I think, in the Wikipedia article "Marker interface pattern". Here's an excerpt that addresses your question directly:
Whereas a typical interface specifies functionality (in the form of method declarations) that an implementing class must support, a marker interface need not do so. The mere presence of such an interface indicates specific behavior on the part of the implementing class. Hybrid interfaces, which both act as markers and specify required methods, are possible but may prove confusing if improperly used.
Aside from the Serializable interface mentioned in the article, there are few others. The only one I can remember off the top of my head is javax.security.auth.callback.
Just thought of another one: javax.security.auth.login.Configuration.Parameters. I'm pretty sure there are more.
Marker interfaces in Java SE 8:
Most widely used:
java.lang.Cloneable
java.io.Serializable
java.util.RandomAccess
java.util.EventListener
Remark: EventListener is officially known as 'tagging interface'.
Others:
java.util.concurrent.CompletableFuture.AsynchronousCompletionTask
java.sql.ParameterMetaData
javax.xml.stream.events.EndDocument
javax.management.loading.PrivateClassLoader
java.security.KeyStore.Entry
java.security.KeyStore.LoadStoreParameter
java.security.KeyStore.ProtectionParameter
java.security.Policy.Parameters
javax.security.auth.callback.Callback
javax.security.auth.login.Configuration.Parameters
Suppose I had an interface with some annotation(s), for example:
#SpecialClass
public interface IFoo { /* ... */ }
And suppose I make a class that implements the interface:
public class Foo implements IFoo { /* ... */ }
Is it possible for class Foo to somehow "inherit" or automatically copy all or some of the annotations from IFoo and its members (e.g. automagically annotate Foo as #SpecialClass, etc.)?
This would be convenient for implementing web service classes (e.g. those generated by the JAX-WS "wsimport" tool) by just implementing their annotated interfaces without explicitly having to copy the interface annotations to the implementing class (e.g. javax.jws.WebService, javax.xml.ws.RequestWrapper, etc).
EDIT: I'm leaving this answer here for general information and future readers, but Andreas pointed out an important bit of the Javadoc which I'd missed:
Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.
In other words, it wouldn't help in this situation. Also it's only useful if you have control over the annotation itself, of course.
I suspect the real answer is that you simply have to apply the annotation everywhere. If you're worried about forgetting one, you might want to write a unit test which finds all your classes (easier said than done, I realise) and checks that the annotation is present for all classes implementing the given interface.
Have you tried applying the Inherited annotation to the SpecialClass annotation itself?
Indicates that an annotation type is automatically inherited. If an Inherited meta-annotation is present on an annotation type declaration, and the user queries the annotation type on a class declaration, and the class declaration has no annotation for this type, then the class's superclass will automatically be queried for the annotation type. This process will be repeated until an annotation for this type is found, or the top of the class hierarchy (Object) is reached. If no superclass has an annotation for this type, then the query will indicate that the class in question has no such annotation.
That certainly sounds like exactly what you want.