Tips
《Effective Java, Third Edition》一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8,甚至9的发布,Java语言发生了深刻的变化。
在这里第一时间翻译成中文版。供大家学习分享之用。

41.使用标记接口定义类型

标记接口(marker interface),不包含方法声明,只是指定(或“标记”)一个类实现了具有某些属性的接口。 例如,考虑Serializable接口(第12章)。 通过实现这个接口,一个类表明它的实例可以写入ObjectOutputStream(或“序列化”)。

你可能会听说过标记注解(条目 39)标记一个接口是废弃过时的。 这个断言是不正确的。 标记接口与标记注解相比具有两个优点。 首先,标记接口定义了一个由标记类实例实现的类型;标记注解则不会。 标记接口类型的存在允许在编译时捕获错误,如果使用标记注解,则直到运行时才能捕获错误。

Java的序列化机制(第6章)使用Serializable标记接口来指示某个类型是可序列化的。 对传递给它的对象进行序列化的ObjectOutputStream.writeObject方法要求其参数可序列化。 如果此方法的参数是Serializable类型,则在编译时会检测到序列化不适当对象的尝试(通过类型检查)。 编译时错误检测是标记接口的意图,但不幸的是,ObjectOutputStream.write API没有利用Serializable接口:它的参数被声明为Object类型,所以尝试序列化一个不可序列化的对象直到运行时才会失败。

标记接口对于标记注解的另一个优点是可以更精确地定位目标。 如果使用目标ElementType.TYPE声明注解类型,它可以应用于任何类或接口。 假设有一个标记仅适用于特定接口的实现。 如果将其定义为标记接口,则可以扩展它适用的唯一接口,保证所有标记类型也是适用的唯一接口的子类型。

可以说,Set接口就是这样一个受限的标记接口。 它仅适用于Collection子类型,但不会添加超出Collection定义的方法。 它通常不被认为是标记接口,因为它改进了几个Collection方法的契约,包括add,equals和hashCode。 但很容易想象一个标记接口,它仅适用于某些特定接口的子类型,并且不会改进任何接口方法的契约。 这样的标记接口可以描述整个对象的一些约束条件(invariant),或者说明实例有资格被某个其他类的方法处理(就像Serializable接口指示实例有资格被ObjectOutputStream处理的方式)。

标记注解优于标记接口的主要优点是它们是较大的注解工具的一部分。因此,标记注解允许在基于注解的框架中保持一致性。

所以什么时候应该使用标记注解,什么时候应该使用标记接口?显然,如果标记适用于除类或接口以外的任何程序元素,则必须使用注解,因为只能使用类和接口来实现或扩展接口。如果标记仅适用于类和接口,那么问自己问题:“可能我想编写一个或多个只接受具有此标记的对象的方法呢?”如果是这样,则应该优先使用标记接口而不是注解。这将使你可以将接口用作所讨论方法的参数类型,这将带来编译时类型检查的好处。如果你能说服自己,永远不会想写一个只接受带有标记的对象的方法,那么最好使用标记注解。另外,如果标记是大量使用注解的框架的一部分,则标记注解是明确的选择。

总之,标记接口和标记注释都有其用处。 如果你想定义一个没有任何关联的新方法的类型,一个标记接口是一种可行的方法。 如果要标记除类和接口以外的程序元素,或者将标记符合到已经大量使用注解类型的框架中,那么标记注解是正确的选择。 如果发现自己正在编写目标为ElementType.TYPE的标记注解类型,请花点时间确定它是否应该是注释类型,是不是标记接口是否更合适

从某种意义来说,本条目与条目22的的意思正好相反,条目22的意思是:“如果你不想定义一个类型,不要使用接口”。本条目的意思是:如果想定义一个类型,一定要使用接口。

Effective Java 第三版——41.使用标记接口定义类型的更多相关文章

  1. 《Effective Java 第三版》目录汇总

    经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...

  2. 《Effective Java 第三版》新条目介绍

    版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...

  3. effective Java 第三版学习笔记

    创建对象类型的 1,静态工厂方法代替构造器 静态工厂方法有名称,不容易混乱他的作用 不必再每次调用他的时候创建实例,创建实例的代价是高的,可以重复利用缓存的对象 静态工厂甚至能返回子类对象,例如在接口 ...

  4. effective-java学习笔记---使用标记接口定义类型40

    标记接口(marker interface),不包含方法声明,只是指定(或“标记”)一个类实现了具有某些属性的接口. 例如,考虑 Serializable 接口.通过实现这个接口,一个类表明它的实例可 ...

  5. Effective Java 第三版——10. 重写equals方法时遵守通用约定

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  7. Effective Java 第三版—— 20. 接口优于抽象类

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. Effective Java 第三版——37. 使用EnumMap替代序数索引

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  9. Effective Java 第三版——39. 注解优于命名模式

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

随机推荐

  1. 牛腩新闻发布系统--学习Web的小技巧汇总

    2014年11月10日,是个难忘的日子,这一天,小编的BS学习开始了,BS的开头,从牛腩新闻发布系统开始,之前学习的内容都是CS方面的知识,软考过后,开始学习BS,接触BS有几天的时间了,跟着牛腩老师 ...

  2. Mybatis插件原理分析(三)分页插件

    在Mybatis中插件最经常使用的是作为分页插件,接下来我们通过实现Interceptor来完成一个分页插件. 虽然Mybatis也提供了分页操作,通过在sqlSession的接口函数中设置RowBo ...

  3. Android 实现Json数据解析,并进行应用!

    从网站上获取数据然后再客户端进行解析是常见的数据交互.下面是常用的一些接口网址: webservice工厂接口 http://www.36wu.com 快递查询接口http://webservice. ...

  4. python类定义

    在我的收藏中有一篇特别详细的类讲解 此处部分内容引自:http://blog.sina.com.cn/s/blog_59b6af690101bfem.html class myclass: 'this ...

  5. [WinForm]dataGridView动态加载以本地图片显示列

    增加一个图片列: C# private void btnQuery_Click(object sender, EventArgs e) { StringBuilder sb=new StringBui ...

  6. 【uWSGI】 listen queue of socket (fd: 3) 错误分析

    现在django的应用基本都是使用uWSGI来部署,类似下面 listen queue of socket "127.0.0.1:9001" (fd: 3) 的错误出现过2次,下面 ...

  7. OC第一天——面向对象

    1.OC: Object- C ,面向对象的语言 2.OC 和 C的区别: <1> oc是 c的超集 ,oc是在c语言的基础上做了扩展,c语言中的所有语法,在oc中都可以使用,甚至你可以在 ...

  8. android ndk编译项目(android-ndk-16r1)

    由于采用android-ndk-16r1版本的ndk来编译 编译的环境之类在这里省略,注意是最后编译的命令如下 Administrator@WIN-AF6P80LVIJ0 ~ $ cd $ANDROI ...

  9. Notepad++ 使用探索

    一.更换主题,视觉享受 1,http://wiki.macromates.com/Themes/UserSubmittedThemes,从网站上下载自己喜欢的主题,解压 2,复制Black Pearl ...

  10. 【Qt编程】Qt学习笔记<一>

    1.      在创建项目时,项目名和路径中都不能出现中文. 2.      可以使用Ctrl + "+"和Ctrl + "-"来改变程序的字体大小(Ctrl+ ...