can marker interface like serializable contain default methods?

前端 未结 4 1910
终归单人心
终归单人心 2021-02-14 12:02

I think it can\'t, because marker interface principle is to not have any methods, but since default methods are not abstract I am not sure.

4条回答
  •  既然无缘
    2021-02-14 12:34

    Although @Azar's answer is correct, we mustn't forget that Effective Java was written before default methods were introduced.

    What is a marker interface?

    There are two ways of looking at marker interfaces:

    1. They are interfaces that declare no methods.
    2. They are interfaces that don't force the implementation of any method.

    The "official" definition is the first one but up until Java 7 those two statements were equivalent. It is a recurring pattern in Effective Java that once you publish an interface, you can't add any methods to it because it would force the implementation of the new methods.

    However, this is exactly the problem default methods are trying to address: to allow for evolution of interfaces without the need to retrofit all classes implementing them. It also makes the two statements above mean slightly different things: a default method clearly violates statement 1 and by design doesn't violate statement 2.

    What does all this mean in practice?

    Imagine that you write an XML serialization engine and you create a marker interface XmlSerializable to go with it:

    public interface XmlSerializable {}
    

    So far, so good. But later on you realise that you actually have some classes that need special treatment, they need to provide their own custom converters. So what you may do is something like this:

    public interface XmlSerializable {
    
       public static final Map CONVERTERS = ...
    
       default Class customConverter() {
          return CONVERTERS.get(this.getClass());
       }
    }
    

    Would that stop XmlSerializable being a marker interface? You can say it still is a marker interface as you don't really add extra behaviour directly to your interface, only extra metadata that influences the behaviour of the serializer engine. On the other hand, this solution allows implementing classes to override customConverter(), which is slightly dodgy, a marker interface shouldn't allow that. (Then again, is Serializable and Cloneable relying on "magic" methods in the implementing class any better? I don't think so.)

    Arguably the example above isn't a very good way to solve this kind of problem, you'd probably be much better off using annotations. But that also holds true for most "true" marker interfaces.

    tl;dr

    We can conclude that an interface with only default methods is more or less equivalent to an empty interface. If you want to make a theoretical distinction and not call it a marker interface, that is of course fine. But there's little practical difference, and given the inherent problems with marker interfaces in general, we should probably avoid them anyway.

提交回复
热议问题