Effective Java 第三版——68. 遵守普遍接受的命名商定
Tips
书中的源代码地址: jbloch/effective-java-3e-source-code
注意,书中的有些代码里方法是基于Java 9 API中的,所以JDK 最好下载 JDK 9以上的版本。
Effective Java, Third Edition
- 遵守普遍接受的命名商定
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]中的话说,“假如长期以来的传统用法要求不遵循这些商定,就不应该盲目地遵循这些商定”。使用常识。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Effective Java 第三版——68. 遵守普遍接受的命名商定