Marker interface doesn\'t has any thing. It contains only interface declarations, then how it is handled by the JVM for the classes which implements this marker interface?
The marker interface helps identify that whether the object under inspection is actually a type (implemented interface) we are interested in. However it is not different than the other interfaces (except that they don't have any behavior obligation)
For example, the ObjectOutputStream
can find that if a class implements Serializable
, then the user has explicitly shown his consent that the object can be serialized.
Take Exampe of clone()
. Actually clone()
is defined inside Object
class. But it is protected
. You can use it only if your class is implementing Cloneable
interface. So what happens is, when you implement Cloneable
, you get the right to use clone()
. Interface doesn't contain any methods! Got it ?
I feel that there might be some logic behind the scenes. How else we get the CloneNotSupportedException when try calling clone() without implementing Cloneable, unless the compiler has some guidelines to check on few things when it sees the clone()!
http://javamagic.wordpress.com/2011/12/02/marker-interface-in-java-what-why-uses-etc/
As per this thread( Confusion in marker interface ), these are all Marker Interfaces .......... Serializable, Clonable, SingleThreadModel, EventListener, RandomAccess, Remote etc.
If there is no logic behind the scene OR no special instructions for JVM/compiler to treat them differently, how come they behave as ONLY what is expected out of them (& JVM/compiler understands the difference between Clonable & Serializable)?
The word "serializable" is confusing in this context, as many novice programmers like myself take it to mean that "serializable" interface does the serialization, i.e. the process of converting the abstract data type to bytes. But as the literature shows, serializable interface is just a "marker" and the real work of converting ADT to bytes (I will call this the process of getting metadata) is done by ObjectOutputStream. Similarly deserialization is done by ObjectInputStream.
then how it is handled by the JVM for the classes which implements this marker interface?
Instances of class implementing a Java marker interface benefit from a specific behavior because some JDK classes or the HotSpot JVM provide a specific behavior for them.
For example take the Serializable
interface.
If you dig into ObjectOutputStream
and ObjectInputStream
you can see that the serialization/unserialization behavior are implemented in.
Here is a snippet of ObjectOutputStream.writeObject0() invoking by ObjectOutputStream.writeObject()
that illustrates that :
public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants {
...
private void writeObject0(Object obj, boolean unshared) throws IOException {
...
if (obj instanceof String) {
writeString((String) obj, unshared);
} else if (cl.isArray()) {
writeArray(obj, desc, unshared);
} else if (obj instanceof Enum) {
writeEnum((Enum<?>) obj, desc, unshared);
} else if (obj instanceof Serializable) {
writeOrdinaryObject(obj, desc, unshared);
} else {
if (extendedDebugInfo) {
throw new NotSerializableException(
cl.getName() + "\n" + debugInfoStack.toString());
} else {
throw new NotSerializableException(cl.getName());
}
}
...
}
}
For the Cloneable
interface, look at the Object.clone()
method and you will see that it refers a native method that applies the Cloneable
specification.
In the HotSpot source code, the src\share\vm\prims\jvm.cpp, you can find the Object.clone()
implementation :
JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
JVMWrapper("JVM_Clone");
Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
const KlassHandle klass (THREAD, obj->klass());
JvmtiVMObjectAllocEventCollector oam;
// I skip all the processing that you can read in the actual source file
...
return JNIHandles::make_local(env, oop(new_obj));
JVM_END
For this marker interface the behavior is not directly implemented in a JDK class but by the JVM itself but the general idea is the same.
Can we create any new marker interfaces ?
If you create your own marker interfaces, you should do as the JVM and the JDK classes do to handle built-in instances of class implementing a Java marker interface : that is adding code to handle specifically the instances of your marker interfaces.
The very good answer of Adamski
shows the general idea to do that.
Your question should really be how does the compiler handle marker interfaces, and the answer is: No differently from any other interface. For example, suppose I declare a new marker interface Foo
:
public interface Foo {
}
... and then declare a class Bar
that implements Foo
:
public class Bar implements Foo {
private final int i;
public Bar(int i) { this.i = i; }
}
I am now able to refer to an instance of Bar
through a reference of type Foo
:
Foo foo = new Bar(5);
... and also check (at runtime) whether an object implements Foo
:
if (o instanceof Foo) {
System.err.println("It's a Foo!");
}
This latter case is typically the driver behind using marker interfaces; the former case offers little benefit as there are no methods that can be called on Foo
(without first attempting a downcast).