Token interfaces in Java?

I was taught that the Marker interface in Java is an empty interface and is used for signature for a compiler or JVM, that objects of a class that implements this interface must be handled in a special way, for example, serialization, cloning, etc.

But lately, I found out that this actually has nothing to do with the compiler or JVM. For example, in the case of the Serializable interface, the writeObject(Object) of ObjectOutputStream does something like instanceOf Serializable to determine whether the class implements Serializable and throws a NotSerializableException respectively. Everything is handled in code, and it looks like a design template, so I think we can define our own marker interfaces.

Now my doubts are:

  • Is the definition of the marker interface mentioned above at the 1st point incorrect? How can we define the Marker interface?

  • And instead of using the instanceOf operator, why can't the method be something like writeObject(Serializable) , so is there a check on the type of compilation time, not the runtime?

  • How are annotations better than marker interfaces?

+115
java design-patterns marker-interfaces
Sep 15 '14 at 14:24
source share
10 answers
  • Is the marker interface definition mentioned above at the 1st point specified? . This is correct in those parts that: (1) the token interface must be empty and (2) the implementation means that it implies some kind of special relation to the executing class. The wrong part is that it means that the JVM or the compiler will treat the objects of this class differently: you correctly noticed that this is the code of the Java class library that treats these objects as cloned, serializable, etc. It has nothing to do with the compiler or JVM.
  • instead of using the instanceOf operator, why the method cannot be something like writeObject(Serializable) , so there is a compilation type check . This avoids polluting your code with the name of the marker interface when a "plain Object " is required. For example, if you create a class that needs to be serializable and has member members, you will either have to cast, or make your objects Serializable at compile time. This is inconvenient because the interface is devoid of any functionality.
  • How are annotations better than Marker interfaces? . They allow you to achieve the same goal as class metadata for your consumers, without creating a separate type for this. Annotations are also more powerful, allowing programmers to pass more complex information to classes that "consume" it.
+99
Sep 15 '14 at 2:37
source share

It is not possible to force Serializable on writeObject , since non-serialization class children can be serializable, but instances can be returned back to the parent class. As a result, a reference to something nonserializable (for example, Object ) does not mean that the mentioned instance really cannot be serialized. For example, in

  Object x = "abc"; if (x instanceof Serializable) { } 

the parent class ( Object ) is not serializable and will be initialized using the constructor without parameters. The value referenced by x , String , is serializable and a conditional statement is executed.

+18
Sep 15 '14 at 14:33
source share

The token interface in Java is an interface without fields or methods. Simply put, an empty interface in Java is called a token interface. Examples of marker interfaces are the Serializable , Cloneable and Remote interfaces. They are used to indicate some information to compilers or JVMs. Therefore, if the JVM sees that the class is Serializable , it can perform some special operation with it. Similarly, if the JVM sees that some class implements Cloneable , it can perform some operations to support cloning. The same is true for RMI and Remote . In short, the token interface indicates a signal or command to the compiler or JVM.

The above began as a copy of a blog post, but has been slightly edited for grammar.

+5
Dec 16 '14 at 4:14
source share

The a / A marker interface, since its name implies existence only to notify everyone that knows about it, that the class declares something. Everything can be JDK classes for the Serializable interface, or any class you write yoursel for custom.

b / If it is a marker interface, it should not imply the existence of any method - it would be better to include the implied method in the interface. But you can decide to design it however you want, if you know why you need it

c / There is a slight difference between an empty interface and an annotation that does not use a value or parameter. But there is a difference: the annotation may declare a list of keys / values ​​that will be available at runtime.

+4
Sep 15 '14 at 14:44
source share
  • It has nothing to do (required) with the JVM and compilers, it has something to do with any testing interests for this marker interface.

  • This is a design decision, and it is made for a good reason. See answer from Audrius Meškauskas.

  • Regarding this particular topic, I do not think it is a question of being better or worse. The token's interface does what it should do all right.

+3
Sep 15 '14 at 14:33
source share

but. I always saw them as a design template and nothing JVM-Special. I used this template in several situations.

from. I believe that using annotations to indicate something is the best solution, and then using marker interfaces. Just because interfaces are primarily aimed at defining common type / class interfaces. They are part of a hierarchy class.

Annotations are aimed at providing meta-information on the code, and I believe that the marker is meta-information. Therefore, they are designed specifically for this case.

+3
Sep 15 '14 at 2:39 on
source share

The main goal of marker interfaces is to create special types in which the types themselves do not have their own behavior.

 public interface MarkerEntity { } public boolean save(Object object) throws InvalidEntityFoundException { if(!(object instanceof MarkerEntity)) { throw new InvalidEntityFoundException("Invalid Entity Found, can't be saved); } return db.save(object); } 

Here, the save method ensures that only class objects implementing the MarkerEntity interface are saved for other types of InvalidEntityFoundException. Thus, the MarkerEntity marker's interface defines a type that adds special behavior to classes that implement it.

Although annotations can now also be used to indicate classes for some special processes, token annotations replace the naming pattern not for Marker interfaces.

But marker annotations cannot completely replace marker interfaces, because; Marker interfaces are used to determine the type (as explained above), where there are no markers as annotations.

Source for marker interface comment

+2
Aug 05 '15 at 16:43
source share

I would say, first of all, that Serializable and Cloneable are bad examples of marker interfaces. Of course, these are interfaces with methods, but they imply methods such as writeObject(ObjectOutputStream) . (The compiler will create a writeObject(ObjectOutputStream) method for you if you do not override it and all objects already have clone() , but the compiler will again create a real clone() method for you, but with caveats.) These are strange extreme cases that really don’t are good examples of design.)

Token interfaces are commonly used for one of two purposes:

1) As a shortcut, to avoid an excessively long type, which can happen with a large number of generics. For example, let's say you have this method signature:

 public void doSomething(Foobar<String, Map<String, SomethingElse<Integer, Long>>>) { ... } 

This is a dirty and annoying type, and, more importantly, difficult to understand. Instead, consider this:

 public interface Widget extends Foobar<String, Map<String, SomethingElse<Integer, Long>>> { } 

Then your method looks like this:

 public void doSomething(Widget widget) { ... } 

It is not only clearer, but now you can use the Javadoc the Widget interface, and it is also easier to search for all occurrences in your widget code.

2) Token interfaces can also be used as a path to the absence of Java intersection types. With the marker interface, you can require that something be of two different types, for example, in a method signature. Say you have an interface widget in your application as described above. If you have a method that requires a widget that also allows you to iterate over it (it invents, but works with me here), the only good solution is to create a marker interface that extends both interfaces:

 public interface IterableWidget extends Iterable<String>, Widget { } 

And in your code:

 public void doSomething(IterableWidget widget) { for (String s : widget) { ... } } 
+1
Sep 15 '14 at 17:47
source share

If the interface does not contain any method and, implementing this interface, if our object gets some opportunity, this type of interface is called marker interfaces.

0
May 30 '16 at 19:30
source share

I did a simple demonstration to resolve doubts # 1 and 2:

We will have a Movable interface that will be implemented by the MobilePhone.java class, and another LandlinePhone.java class that will NOT implement the Movable interface.

Our marker interface:

 package com; public interface Movable { } 

LandLinePhone.java and MobilePhone.java

  package com; class LandLinePhone { // more code here } class MobilePhone implements Movable { // more code here } 

Our exception class: com package;

public class NotMovableException extends Exception {

 private static final long serialVersionUID = 1L; @Override public String getMessage() { return "this object is not movable"; } // more code here } 

Our test class: TestMArkerInterface.java

 package com; public class TestMarkerInterface { public static void main(String[] args) throws NotMovableException { MobilePhone mobilePhone = new MobilePhone(); LandLinePhone landLinePhone = new LandLinePhone(); TestMarkerInterface.goTravel(mobilePhone); TestMarkerInterface.goTravel(landLinePhone); } public static void goTravel(Object o) throws NotMovableException { if (!(o instanceof Movable)) { System.out.println("you cannot use :" + o.getClass().getName() + " while travelling"); throw new NotMovableException(); } System.out.println("you can use :" + o.getClass().getName() + " while travelling"); }} 

Now that we are executing the main class:

 you can use :com.MobilePhone while travelling you cannot use :com.LandLinePhone while travelling Exception in thread "main" com.NotMovableException: this object is not movable at com.TestMarkerInterface.goTravel(TestMarkerInterface.java:22) at com.TestMarkerInterface.main(TestMarkerInterface.java:14) 

So which class implements the marker interface, Movable will pass the test, otherwise an error message will appear.

This is a way to test the instanceOf operator for Serializable, Cloneable, etc.

0
Sep 04 '18 at 12:41
source share



All Articles