Marker Interfaces in Java?

2019-01-04 05:28发布

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:

  1. Is the definition of a marker interface mentioned above in 1st point wrong? How can we define a Marker interface then?

  2. And instead of using the instanceOf operator why can't the method be something like writeObject(Serializable) so that there is a compile-time type checking rather than runtime?

  3. How are Annotations better than Marker Interfaces?

10条回答
女痞
2楼-- · 2019-01-04 05:57

a/ A marker interface as its name suggest exists only to notify anything that knows about it that a class declares something. The anything can be the JDK classes for the Serializable interface, or any class you write yoursel for a custom one.

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 as you want if you know why you need it

c/ There is little difference between an empty interface and an annotation that uses no value or parameter. But the difference is there : an annotation can declare a list of keys/values that will be accessible at run time.

查看更多
走好不送
3楼-- · 2019-01-04 05:59
  1. It has nothing to do (necessarily) with the JVM and the compilers, it has something to do with any code which is interested in and is testing for a given marker interface.

  2. It's a design decision and it's done for a good reason. See the answer from Audrius Meškauskas.

  3. With respect to this particular topic, I don't think it's a matter of being better or worse. The marker interface is doing what it's supposed to do just fine.

查看更多
兄弟一词,经得起流年.
4楼-- · 2019-01-04 06:08
  1. Is the definition of a marker interface mentioned above in 1st point wrong? - It is correct in the parts that (1) a marker interface must be empty, and (2) implementing it is meant to imply some special treatment of the implementing class. The part that is incorrect is that it implies that JVM or the compiler would treat the objects of that class differently: you are correct in observing that it is the code of Java class library that treats these objects as cloneable, serializable, etc. It has nothing to do with the compiler or the JVM.
  2. instead of using the instanceOf operator why can't the method be something like writeObject(Serializable) so that there is a compile-time type checking - This lets you avoid polluting your code with the name of the marker interface when a "plain Object" is needed. For example, if you make a class that needs to be serializable, and has object members, you would be forced to either do casting or make your objects Serializable at compile time. This is inconvenient, because the interface is devoid of any functionality.
  3. How Annotations are better than Marker Interfaces? - They let you achieve the same purpose of conveying metadata about the class to its consumers without creating a separate type for it. Annotations are more powerful, too, letting programmers pass more sophisticated information to classes that "consume" it.
查看更多
手持菜刀,她持情操
5楼-- · 2019-01-04 06:09

A marker interface in Java is an interface with no fields or methods. Put more simply, an empty interface in Java is called a marker interface. Examples of marker interfaces are the Serializable, Cloneable and Remote interfaces. These are used to indicate some information to compilers or JVMs. So if the JVM sees that a class is Serializable, it can do some special operation on it. Similarly, if the JVM sees some class is implementing Cloneable, it can perform some operations to support cloning. The same is true for RMI and the Remote interface. So in short, a marker interface indicates a signal or a command to the compiler or JVM.

The above started out as a copy of a blog post but has been lightly edited for grammar.

查看更多
【Aperson】
6楼-- · 2019-01-04 06:11

I would argue first-off that Serializable and Cloneable are bad examples of marker interfaces. Sure, they're interfaces with methods, but they imply methods, such as writeObject(ObjectOutputStream). (The compiler will create a writeObject(ObjectOutputStream) method for you if you don't override it, and all objects already have clone(), but the compiler will again create a real clone() method for you but with caveats. Both of these are weird edge cases that really aren't good design examples.)

Marker interfaces are generally used for one of two purposes:

1) As a shortcut to avoid an excessively long type, which can happen with lots of generics. For instance, say you have this method signature:

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

That's messy and annoying to type, and more importantly, difficult to understand. Consider this instead:

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

Then your method looks like this:

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

Not only is it clearer, but you can now Javadoc the Widget interface, and it's also easier to search for all occurrences in your code of Widget.

2) Marker interfaces can also be used as a way around Java's lack of intersection types. With a marker interface, you can require something to be of two different types, such as in a method signature. Say you have some interface Widget in your application, like we described above. If you have a method that requires a Widget that also happens to let you iterate over it (it's contrived, but work with me here), your 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) { ... }
}
查看更多
混吃等死
7楼-- · 2019-01-04 06:11

If an interface does not contain any method and by implementing that interface if our object will get some ability such type of interfaces are called marker interfaces.

查看更多
登录 后发表回答