I was being taught that Marker interface in Java is an empty interface and is used to signal to compiler or JVM that the objects of the class implementing this interface must be treated in a special way, like serializing, cloning, etc.
But lately I have learned that it actually has nothing to do with the compiler or the JVM. For example, in case of Serializable
interface the method writeObject(Object)
of ObjectOutputStream
does something like instanceOf Serializable
to detect whether the class implements Serializable
& throws NotSerializableException
accordingly.
Everything is handled in the code and this seems to be a design-pattern so I think we can define our own marker interfaces.
Now my doubts:
Is the definition of a marker interface mentioned above in 1st point wrong? How can we define a Marker interface then?
And instead of using the
instanceOf
operator why can't the method be something likewriteObject(Serializable)
so that there is a compile-time type checking rather than runtime?How are Annotations better than Marker Interfaces?
a. I have always seen them as a design pattern and nothing JVM-Special I have used that pattern in several situations.
c. I beleive that using Annotations to mark something is a better solution then using marker interfaces. Simply because Interfaces are in the first place aimed to define common interfaces of Types / Classes. They are part of the class-hierachy.
Annotations are aimed to provide Meta-Informations to Code, and I think that marker are meta-informations. So they are exactly for that use-case.
I have made a simple demonstration to resolve doubt no 1 and 2 :
We will be having Movable interface which will be implemented by MobilePhone.java Class and one more class LandlinePhone.java which do NOT implement Movable interface
Our marker Interface:
LandLinePhone.java and MobilePhone.java
Our Custom Exception Class : package com;
public class NotMovableException extends Exception {
Our Test class : TestMArkerInterface.java
Now when we execute main class :
So Which ever class implements marker interface Movable will pass the test else error message will be displayed.
This is the way instanceOf operator check is done for Serializable, Cloneable etc
The main purpose of marker interfaces is to create special types where types themselves have no behavior of their own.
Here save method makes sure that only the objects of classes that implement the MarkerEntity interface are saved, for other types InvalidEntityFoundException is thrown. So here MarkerEntity marker interface is defining a type that adds special behavior to the classes implementing it.
Though annotations can also used now to mark classes for some special treatments but marker annotations are replacement for naming pattern not for Marker interfaces.
But marker annotations can't fully replace the marker interfaces because; marker interfaces are used to define type (as already explained above) where as marker annotations do not.
Source for marker interface comment
It is not possible to enforce
Serializable
onwriteObject
because children of non-serializable class can be serializable, but they instances may be upcasted back to the parent class. As a result, holding a reference to something non-serializable (likeObject
) does not mean that the referred instance really cannot be serialized. For instance inthe parent class (
Object
) is not serializable and would be initialized using its parameter-less constructor. The value referenced byx
,String
, is serializable and the conditional statement would run.