Tips
书中的源代码地址:
注意, 书中的有些代码里方法是基于 Java 9 API 中的, 所以 JDK 最好下载 JDK 9 以上的版本.
遵守普遍接受的命名约定
Java 平台有一组完善的命名约定 (naming conventions), 其中许多约定包含在 Java 语言规范[JLS, 6.1] 中. 宽泛地说, 命名约定分为两类: 字面 (typographical) 的和语法的(grammatical).
只有少量的字面的命名约定, 包括包, 类, 接口, 方法, 属性和类型变量. 你不应该违反它们, 而且没有理由去违反. 如果 API 违反了这些约定, 那么它可能很难使用. 如果实现违反了这些规则, 可能很难维护. 在这两种情况下, 违反约定都有可能使其他使用代码的程序员感到困惑和恼怒, 并可能导致他们做出错误的假设, 从而导致错误. 本条目概述了各个命名约定.
包和模块名称应该是分层的, 每个部分以句点分隔. 每个部分应包含小写字母字符, 很少包含数字. 任何在你的组织外部使用的包的名称都应该以你的组织的 Internet 域名开头, 但包名正好相反, 例如, edu.cmu,com.google,org.eff. 名称以 java 和 javax 开头的标准类库和可选包是此规则的例外. 用户不得创建名称以 java 或 javax 开头的包或模块. 可以在 JLS [JLS, 6.1]中找到将 Internet 域名转换为包名称前缀的详细规则.
包名的其余部分应该由描述包的一个或多个组件构成. 组件应该很短, 通常为 8 个或更少的字符. 鼓励使用有意义的缩写, 例如 util 而不是 utilities. 缩写词是可以接受的, 例如 awt. 组件通常应该由一个单词或缩写组成.
除了 Internet 域名之外, 许多包的名称只包含一个组件. 其他组件适用于大型设施, 其大小要求将其分解为非正式层次结构. 例如, javax.util 包具有丰富的包层次结构, 其名称如 java.util.concurrent.atomic. 这样的包被称为子包, 尽管几乎没有语言对包层次结构提供支持.
类和接口名称 (包括枚举和注解类型名称) 应由一个或多个单词组成, 每个单词的首字母大写, 例如 List 或 FutureTask. 除了首字母缩略词和某些常用缩写 (如 max 和 min) 之外, 应避免使用缩写. 关于首字母缩略词是大写还是仅首字母大写, 存在一些分歧. 虽然一些程序员仍然使用大写字母, 但是可以做出强有力的论证, 只支持大写第一个字母: 即使多个首字母缩写连续出现, 仍然可以知道一个单词从哪里开始, 下一个单词从哪里结束. 你更喜欢看哪个类名, HTTPURL 或 HttpUrl?
方法和属性名遵循与类和接口名相同的字面约定, 除了方法或属性名的第一个字母应该是小写, 例如 remove 或 ensureCapacity. 如果首字母缩略词作为方法或属性名称的第一个单词出现, 则它应该是小写的.
前面规则的唯一例外是 "常量属性", 它的名称应该由一个或多个大写单词组成, 由下划线分隔, 例如 VALUES 或 NEGATIVE_INFINITY. 常量属性是一个静态的 final 属性, 其值是不可变的. 如果静态 final 属性具有基本类型或不可变引用类型(条目 17), 那么它就是常量属性. 例如, 枚举常量是常量属性. 如果静态 final 属性有一个可变的引用类型, 那么如果所引用的对象是不可变的, 那么它仍然可以是一个常量属性. 注意, 常量属性是唯一推荐的下划线用法.
局部变量名称与成员名称具有相似的字面命名约定, 但允许使用缩写除外, 单个字符和短字符序列的含义取决于它们出现的上下文, 例如 i,denom,houseNum. 输入参数是一种特殊的局部变量. 它们的名称应该比普通的局部变量更加仔细, 因为它们的名称是其方法文档中不可或缺的一部分.
类型参数名通常由单个字母组成. 最常见的是以下五种类型之一: T 表示任意类型, E 表示集合的元素类型, K 和 V 表示映射的键和值类型, X 表示异常. 方法的返回类型通常为 R. 任意类型的序列可以是 T,U,V 或 T1,T2,T3.
为了快速参考, 下表列出了字面约定的示例.
标识符类型 | 示例 |
---|---|
包名或模块 | org.junit.jupiter.api, com.google.common.collect |
类或接口 | Stream, FutureTask, LinkedHashMap, HttpClient |
方法或属性 | remove, groupingBy, getCrc |
常量属性 | MIN_VALUE, NEGATIVE_INFINITY |
局部变量 | i, denom, houseNum |
类型参数 | T, E, K, V, X, R, U, V, T1, T2 |
语法命名约定比字面约定更灵活, 也更有争议. 包没有语法命名约定. 可实例化的类, 包括枚举类型, 通常使用一个或多个名词短语来命名, 例如 Thread,PriorityQueue 或 ChessPiece. 不可实例化的实用程序类 (条目 4) 通常使用复数名词来命名, 例如 Collector 或 Collections. 接口的名称类似于类, 例如 Collection 或 Comparator, 或者以 able 或 ible 结尾的形容词, 例如 Runnable,Iterable 或 Accessible. 因为注解类型有如此多的用途, 所以没有哪部分词性占主导地位. 名词, 动词, 介词和形容词都很常见, 例如, BindingAnnotation,Inject,ImplementedBy 或 Singleton.
执行某些操作的方法通常使用动词或动词短语 (包括对象) 命名, 例如 append 或 drawImage. 返回 boolean 类型的方法通常具有以单词 is, 或不太常用的 has 开头的名称, 后跟名词, 名词短语或任何用作形容词的单词或短语, 例如 isDigit,isProbablePrime,isEmpty, isEnabled, 或 hasSiblings.
方法返回被调用对象的非 boolean 的方法或属性, 通常使用以 get 开头的名词, 名词短语或动词短语来命名, 例如 size,hashCode 或 getTime. 有一种说法是, 只有第三种形式 (以 get 开头) 才是可接受的, 但这种说法几乎没有根据. 前两种形式的代码通常可读性更强, 例如:
- if (car.speed()> 2 * SPEED_LIMIT)
- generateAudibleAlert("Watch out for cops!");
以 get 开头的形式起源于基本过时的 Java bean 规范, 该规范构成了早期可重用组件体系结构的基础. 有一些现代工具继续依赖于 Beans 命名约定, 你可以随意在任何与这些工具结合使用的代码中使用它. 如果类同时包含相同属性的 setter 和 getter, 则遵循这种命名约定也有很好的先例. 在本例中, 这两个方法通常被命名为 getAttribute 和 setAttribute.
一些方法名称值得特别提及. 转换对象类型, 返回不同类型的独立对象的实例方法通常称为 toType, 例如 toString 或 toArray. 返回类型与接收对象类型不同的视图 (条目 6) 的方法通常称为 asType, 例如 asList. 返回与调用它们的对象具有相同值的基本类型的方法通常称为 typeValue, 例如 intValue. 静态工厂的常用名称包括 from,of,valueOf,instance,getInstance,newInstance,getType 和 newType(条目 1, 第 9 页).
属性名称的语法约定不太完善, 并且不如类, 接口和方法名称那么重要, 因为设计良好的 API 包含很少的暴露属性. boolean 类型的属性通常被命名为 boolean 访问器方法, 省略了初始的 is 前缀, 例如, initialized,composite. 其他类型的属性通常以名词或名词短语命名, 例如 height,digits 或 bodyStyle. 局部变量的语法约定类似于属性, 但甚至更弱.
总之, 将标准命名约定内在化, 并将其作为第二天性来使用. 字面约定是直接的, 而且在很大程度上是明确的; 语法约定更加复杂和松散. 引用 Java 语言规范 [JLS, 6.1] 中的话说,"如果长期以来的传统用法要求不遵循这些约定, 就不应该盲目地遵循这些约定". 使用常识.
来源: https://www.cnblogs.com/IcanFixIt/p/10606047.html