用Java标记接口

什么是标记接口以及它们用于什么?

因为有时候,如果某个类型的某个属性可以用作类型本身,那么确实有意义 – 可以想到Serializable 。 如果我做这样的方法:

 public void save(Object data){ ... } 

…你真的不知道如何保存这些data 。 VM序列化? Bean属性序列化? 一些自制方案? 如果你这样写:

 public void save(Serializable data){ ... } 

……很明显(如果只有ObjectOutputStream的设计者使用过这种可能性!)。 有时,当您想要将元数据添加到类型时使用注释是有意义的,但在这种情况下,我会争论标记接口。

标记界面通常具有与之相关的一些魔力:要么直接内置到VM中,要么使用reflection。 因为魔术在技术上可以应用于任何类,所以你使用标记来表明你对魔法的理解以及它是否适用于你的类。

Bloch的“Effective Java”中讨论了标记接口与注释的问题,该部分的部分内容可在此处的 Google书籍中找到

它曾用于提及类的某些属性(如Serializable显示,允许该类序列化)。 现在注释可以完成这项工作。

除了其他答案之外,标记接口还可用于指定未被其他已实现的接口inheritance的类的其他属性。 其中一个例子是接口RandomAccess 。 它表示可以随意访问而不会降低性能的集合,并且不必通过迭代器访问以实现该性能。

您可以使用标记界面标记您的类,以向您的类的开发人员和消费者说明您明确支持该function。 想想Serializable; 需要持久化Session并使用序列化来执行此操作的人可以安全地使用您的类的对象。

它可以进一步用于reflection; 现在通常使用注释来执行此操作,但在过去,您可以检查一个类,检查它是否实现了某个接口(如DAO),如果是,则进一步处理该对象(我在这里考虑实体注释) )。

标记接口是内部没有抽象方法的接口,它们用于为实现它们的类添加数据类型,并且是其他接口的父接口(特别是在接口中具有多个inheritance)

 public interface name {} public interface john1 {} public interface john2 {} public interface Demo extends john1 , john2 , name {} 

**当JVM看到名称界面时,它会发现Demo将发挥特定的cenario。

我还想补充一下,您可以使用标记接口来限制实例的所有权:

 interface IFlumThing; interface IFlooThing; class BaseThing {...} class FlumThing extends BaseThing implements IFlumThing {}; class FlooThing extends BaseThing implements IFlooThing {}; class Flum { addThing(IFlumThing thing){...}; } class Floo { addThing(IFlooThing thing){...}; }