Tips

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

在这里第一时间翻译成中文版。供大家学习分享之用。

22. 接口仅用来定义类型

当类实现接口时,该接口作为一种类型(type),可以用来引用类的实例。因此,一个类实现了一个接口,因此表明客户端可以如何处理类的实例。为其他目的定义接口是不合适的。

一种失败的接口就是所谓的常量接口(constant interface)。 这样的接口不包含任何方法; 它只包含静态final属性,每个输出一个常量。 使用这些常量的类实现接口,以避免需要用类名限定常量名。 这里是一个例子:

// Constant interface antipattern - do not use!
public interface PhysicalConstants {
// Avogadro's number (1/mol)
static final double AVOGADROS_NUMBER = 6.022_140_857e23; // Boltzmann constant (J/K)
static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23; // Mass of the electron (kg)
static final double ELECTRON_MASS = 9.109_383_56e-31;
}

常量接口模式是对接口的糟糕使用。类在内部使用一些常量,完全属于实现细节。实现一个常量接口会导致这个实现细节泄漏到类的导出API中。对类的用户来说,类实现一个常量接口是没有意义的。事实上,它甚至可能使他们感到困惑。更糟糕的是,它代表了一个承诺:如果在将来的版本中修改了类,不再需要使用常量,那么它仍然必须实现接口,以确保二进制兼容性。如果一个非final类实现了常量接口,那么它的所有子类的命名空间都会被接口中的常量所污染。

Java平台类库中有多个常量接口,如java.io.ObjectStreamConstants。 这些接口应该被视为不规范的,不应该被效仿。

如果你想导出常量,有几个合理的选择方案。 如果常量与现有的类或接口紧密相关,则应将其添加到该类或接口中。 例如,所有数字基本类型的包装类,如IntegerDouble,都会导出MIN_VALUEMAX_VALUE常量。 如果常量最好被看作枚举类型的成员,则应该使用枚举类型(条目 34)导出它们。 否则,你应该用一个不可实例化的工具类来导出常量(条目 4)。 下是前面所示的PhysicalConstants示例的工具类的版本:

// Constant utility class
package com.effectivejava.science; public class PhysicalConstants {
private PhysicalConstants() { } // Prevents instantiation public static final double AVOGADROS_NUMBER = 6.022_140_857e23;
public static final double BOLTZMANN_CONST = 1.380_648_52e-23;
public static final double ELECTRON_MASS = 9.109_383_56e-31;
}

顺便提一下,请注意在数字文字中使用下划线字符(_)。 从Java 7开始,合法的下划线对数字字面量的值没有影响,但是如果使用得当的话可以使它们更容易阅读。 无论是固定的浮点数,如果他们包含五个或更多的连续数字,考虑将下划线添加到数字字面量中。 对于底数为10的数字,无论是整型还是浮点型的,都应该用下划线将数字分成三个数字组,表示一千的正负幂。

通常,实用工具类要求客户端使用类名来限定常量名,例如PhysicalConstants.AVOGADROS_NUMBER如果大量使用实用工具类导出的常量,则通过使用静态导入来限定具有类名的常量

// Use of static import to avoid qualifying constants
import static com.effectivejava.science.PhysicalConstants.*; public class Test {
double atoms(double mols) {
return AVOGADROS_NUMBER * mols;
}
...
// Many more uses of PhysicalConstants justify static import
}

总之,接口只能用于定义类型。 它们不应该仅用于导出常量。

Effective Java 第三版——22. 接口仅用来定义类型的更多相关文章

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

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

  2. Effective Java 第三版——65. 接口优于反射

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

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

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

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

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

  5. Effective Java 第三版——41.使用标记接口定义类型

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

  6. Effective Java 第三版——44. 优先使用标准的函数式接口

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

  7. Effective Java 第三版——14.考虑实现Comparable接口

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

  8. Effective Java 第三版——21. 为后代设计接口

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

  9. Effective Java 第三版——38. 使用接口模拟可扩展的枚举

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

随机推荐

  1. iOS UITabView简写瀑布流

    代码demo 一.tabViewCell,通过image的比例高算出cell 的高度 #import "TableViewCell.h" @implementation Table ...

  2. Keras的安装与配置

    Keras是由Python编写的基于Tensorflow或Theano的一个高层神经网络API.具有高度模块化,极简,可扩充等特性.能够实现简易和快速的原型设计,支持CNN和RNN或者两者的结合,可以 ...

  3. 自定义bootstrap样式-9行样式自定义漂亮大气bootstrap导航栏

    有人说前端发展太快,框架太多,各有所需,各有所长.看看这幅图,估计都知道这些框架,但是大部分公司中实际要用到的也就那么几个. 发展再快,框架再多.还是得回到原点,不就是Html+Css+JavaScr ...

  4. 如何在MQ中实现支持任意延迟的消息?

    什么是定时消息和延迟消息? 定时消息:Producer 将消息发送到 MQ 服务端,但并不期望这条消息立马投递,而是推迟到在当前时间点之后的某一个时间投递到 Consumer 进行消费,该消息即定时消 ...

  5. bzoj 2588 Count on a tree

    Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...

  6. JVM类加载机制以及类缓存问题的处理

    一:JVM类加载机制 和 类缓存问题的处理 当一个java项目启动的时候,JVM会找到main方法,根据对象之间的调用来对class文件和所引用的jar包中的class文件进行加载(其步骤分为加载.验 ...

  7. class_copyIvarList方法获取实例变量问题引发的思考

    在runtime.h中,你可以通过其中的一个方法来获取实例变量,那就是class_copyIvarList方法,具体的实现如下: - (NSArray *)ivarArray:(Class)cls { ...

  8. JavaScript的简单入门

    一.导读 简介:JavaScript简称js,是基于对象和事件驱动的脚本语言,主要运用于客户端.原名LiveScript,本身和Java没有任何关系,但语法上很类似. 特点:交互性(它可以做的就是信息 ...

  9. 学习rollup.js模块文件打包

    学习rollup.js模块文件打包 一:rollup 是什么?Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码. webpack 和 Rollup 对比不同点 ...

  10. 微信公众号H5支付遇到的那些坑

    简史 官方文档说的很清楚,商户已有H5商城网站,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程. 当然,最近微信支付平台也加入了纯H5支付,也就是说用户可以在微信以外的 ...