美文网首页
Effective Java(3rd)-Item41 使用标记接

Effective Java(3rd)-Item41 使用标记接

作者: 难以置信的优雅 | 来源:发表于2018-09-18 14:59 被阅读0次

  一个标记接口是一个接口,没有包含方法声明仅委托(或“标记”)一个实现该接口的类具有某些属性。比如,考虑Serializable接口(第12章).通过实现这个接口,一个类指示了它的实例可以被写为一个ObjectOutputStream(或“序列化的”)。
  你可能会听说标记注解( item39 )导致标记接口过时了。这个断言是不正确的。标记接口比标记注解有两个优势。首先也是最重要的, 标记接口定义由标记类的实例实现的类型,标记注解不能。标记类下的存在允许你在编译时间捕获错误,如果你使用一个标记注解,在运行时间之前不能捕获异常。

  Java的序列化设施(第六章)使用Serializable标记接口来指示一个类型是可序列化的。ObjectOutputStream.writeObject方法,用来传递序列化的对象,需要它的参数是被序列化的。如果该方法的参数拥有Serializable类型,在编译时(通过类型检查)会检测到序列化了不合适的对象。编译时间错误的检测是标记接口的意图,但是不幸的是, ObjectOutputStream.write API并没有利用Serializable接口的优势:它的参数被声明为Object类型,所以尝试序列化一个未序列化的对象在运行时间并不会失败。
  另一个标记接口比标记注解的好的地方是它们定位更精确。如果一个注解类型通过目标ElementType.TYPE声明,它可以应用于任何类或接口。假设你有一个标记只适用于特定接口的实现。如果你定义它作为标记接口,你可以让他继承其适用的仅有的接口,确保所有标记类型也都是其适用的唯一接口的子类型。
  可以说,Set接口就只是一个 受限制的标记接口。它只对Collection的子类型适用,但是除了通过Collection定义的方法,它没有添加任何方法。它通常不被认为是标记接口因为它改善了一些Collection方法的契约,包括add,equals,hashCode.但是很容易想象一个标记接口只适用于一些特定接口的子类型,并没有改善任何接口的方法。这样的标记接口可能描述了整个对象的一些不变量或指示实例够资格来处理一些其他类的方法(通过Serializable接口指示实例符合ObjectOutputStream处理的条件)
  标记注解比标记接口的主要优势是它们是更大的注解工具的一部分。因此,标记注解允许在基于注解的框架中保持一致性。
  那么我们什么时候应该用标记注解什么时候应该用标记接口呢?如果标记应用于任何程序元素而不是类或接口时,明显你必须使用一个注解,因为只有类和接口能够实现或继承接口。如果只允许标记类和接口,问你自己一个问题:我想要编写一个或更多只接受这个标记的对象的方法嘛?如果是,你应该使用一个标记接口而不是标记注解。这将使您能够将接口用作相关方法的参数类型,这将带来编译时类型检查的好处。如果你可以说服自己你将永远不会想要编写一个方法只接受标记的对象,你大概更希望使用标记注解。此外,如果标记是大量使用注解的框架的一部分,那么标记注解就是明显的选择。
  总之,标记接口和标记注解都有它们的使用场景。如果你想要定义一个没有任何新方法关联的类型,标记接口才是解决之道。如果你想要标记程序元素而不是类和接口或适应在框架中的标记,并早已有了注解类型的大量使用,标记注解就是正确的选择。 如果您发现自己正在编写目标为ElementType.TYPE的标记注解类型,花点时间弄清楚它究竟应该是注解类型,还是标记接口更合适。
  某种意义上说,这个item是Item22( item22 )的倒序,”如果你不想要定义一个类型,不要使用一个接口“,最接近的说法是,”如果你确实想要定义一个类型,使用接口“。

本文写于2019.7.10,历时2天

相关文章

网友评论

      本文标题:Effective Java(3rd)-Item41 使用标记接

      本文链接:https://www.haomeiwen.com/subject/nstpnftx.html