Effective.Java第56-66条(规范相关)
56. 为所有已公开的API元素编写文档注释
要正确地记录API,必须在每个导出的类、接口、构造方法、方法和属性声明之前加上文档注释。如果一个类是可序列化的,还需要记录它的序列化形式。
文档注释在源代码和生成的代码中都应该是可读的通用原则。
类或接口中的两个成员方法或构造方法不应具有相同的概要描述。
总结起来就是一句话,文档注释要规范。
阿里规约如下:
【强制】类、类属性、类方法的注释必须使用 Javadoc 规范,使用/**内容*/格式,不得使用 // xxx 方式。
【强制】所有的抽象方法(包括接口中的方法) 必须要用 Javadoc 注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。
【强制】所有的类都必须添加创建者和创建日期。
【强制】方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。
【强制】所有的枚举类型字段必须要有注释,说明每个数据项的用途
57. 最小化局部变量的作用域
最重要的技术就是在使用变量之前再首次声明变量。
几乎每个局部变量都应该包含一个初始化器。
58. for-each循环优于普通for循环
for-each官方称为增强for循环。如下:看到冒号(:)读作in。下面的循环读作对于elements中的每个元素e。
for (Element e: elements) {
}
有三种情况不能使用for-each循环:
有损过滤:如果需要遍历集合并删除元素不能用,需要使用迭代器。
转换:如果需要转换集合的部分元素或值,需要用到下标的话需要用普通for循环。
并行迭代:如果需要并行遍历多个集合,那么需要显示地控制迭代器或索引遍历。可以使用普通for循环。
for-each循环在清晰度,灵活性和错误预防方面提供了超越传统for循环的优势,而且没有性能损失。
59. 了解并使用库
通过使用标准库,你可以利用编写它的专家的知识和以前使用者的经验。
每个程序员都应该熟悉java.lang、java.util和java.io的基础知识以及其子包。其实java.util.concurrent包也是非常重要的。
第三方jar包的话有commons-lang、commons-io、commons-collections相关jar包。
总之,不要重复造轮子。如果你需要做一些看起来相当常见的事情,那么库中可能已经有一个工具可以做你想做的事情。
60. 若需要精确答案就避免使用float和double
float和double不能再需要精确计算的地方使用,尤其是货币计算。
比如:
float num1 = 1.6F;
float num2 = 0.9255F;
System.out.println(num1 - num2);
结果:
0.67450005
解决办法:使用BigDecimal,注意使用其String类型的构造方法不要使用float或double,避免在计算中引入不准确的值。
float num1 = 1.6F;
float num2 = 0.9255F; BigDecimal bidnumber1 = new BigDecimal(String.valueOf(num1));
BigDecimal bidnumber2 = new BigDecimal(String.valueOf(num2)); BigDecimal subtract = bidnumber1.subtract(bidnumber2);
float floatValue = subtract.floatValue();
System.out.println(floatValue);
总之,对于任何需要精确答案的计算,不使用float或double。如果希望系统处理十进制小数点,并且不介意不使用基本类型带来的不便和成本,就使用BigDecimal。使用BigDecimal的另一个好处是,它可以完全控制舍入模式。
61. 基本数据类型优于包装类型
自动装箱和自动拆箱模糊了基本类型和包装类型之间的区别,但不会消除它们。主要区别有下面三条:
第一:基本类型只有它们的值,而包装类型具有与值不同的标识,换句话说,两个相同包装类型具有相同的值和不同的标识。
第二:基本类型只有全功能值,而包装类型除了基本类型的所有功能值外,还有一个非功能值,即null。(将 == 操作符应用于包装类型几乎都是错误的)
第三:基本类型比包装类型更节省时间和空间。
在操作中混合使用基本类型和包装类型时,包装类型就会自动拆箱,如果一个空对象自动拆箱会引发NPE空指针异常。如下:
Long sum = 0L;
for (int i = 0; i < 500; i++) {
sum += i;
}
这个程序比它预期的慢的多,因为它意外地声明了一个局部变量(sum),它是包装类型而不是基本类型。变量会被反复的装箱和拆箱,导致产生明显的性能问题。
什么情况下应该使用包装类型?
第一个是作为集合中的元素、键值;第二个是进行反射方法调用时必须使用包装类型。
62. 当使用其他类型更合适时应避免使用字符串
字符串类型是其他值类型的糟糕替代品。比如int、float就用其类型表示,不能用字符串表示;表示是或否就用布尔类型。
字符串是枚举类型的糟糕替代品。
字符串是聚合类型的糟糕替代品。
总之,当存在或可以编写更好的类型时,应避免使用字符串来表示对象。
63. 当心字符串链接引起的性能问题
字符串链接操作(+)是将几个字符串拼接在一起的简便方法。我们也知道字符串的拼接操作是通过生成StringBuilder并调用其append方法进行拼接。
当拼接项足够多时,考虑使用StringBuilder的append方法代替。
64. 通过接口引用对象
如果存在合适的接口类型,那么应该使用接口类型声明参数、返回值、变量和字段。唯一真正需要引用对象的类的时候是使用构造函数创建它的时候。
如果养成使用接口引用对象的习惯,将会更加灵活。如果决定切换实现,只需在构造函数切换类名(或使用不同的静态工厂)
注意:如果原实现提供了接口约定的其他特殊方法,并且依赖于该功能,那么只能用该类接收对象。比如:如下代码只能用LinkedList接收对象引用。
LinkedList<String> lists = new LinkedList<>();
lists.peekFirst();
如果没有合适的接口存在,那么类引用对象是完全合适的。比如String等。
65. 接口优于反射
核心反射机制 java.lang.reflect 提供对任意类的编程访问。给定一个 Class 对象,你可以获得Constructor、Method 和 Field 实例,分别代表了该 Class 实例所表示的类的构造器、方法和字段。这些对象提供对类的成员名、字段类型、方法签名等的编程访问。
此外,Constructor、Method 和 Field 实例允许你反射性地操作它们的底层对应项:你可以通过调用 Constructor、Method 和 Field 实例上的方法,可以构造底层类的实例、调用底层类的方法,并访问底层类中的字段。例如,Method.invoke 允许你在任何类的任何对象上调用任何方法(受默认的安全约束)。
反射允许一个类使用另一个类,即使在编译前者时后者并不存在。然而,这种能力是有代价的:
(1)失去了编译时类型检查的所有好处,包括异常检查。
(2)执行反射访问所需的代码笨拙又冗长。
(3)性能降低。反射比普通方法调用慢得多。
有一些复杂的程序需要用到反射,比如代码分析工具和依赖注入框架。
通过非常有限的形式使用反射,你可以获得反射的许多好处,同时花费的代价很少。
反射的合法用途(很少)是管理类对运行时可能不存在的其他类、方法或字段的依赖关系。如果编写的程序必须在编译时处理未知 类,则应该尽可能使用反射实例化对象,并在编译时已知的接口或超类访问对象。(比如静态工厂的反射创建对象)
66. 明智审慎地本地方法
Java本地接口(JNI)允许Java调用本地方法,这些方法是c或c++编写而成。本地方法一般有三种用途:提供对特定于平台的设施的访问、提供对现有本地代码库的访问、通过本地语言辨析应用程序中注重性能的部分以提高性能。
为了提高性能,很少建议使用本地方法。
Effective.Java第56-66条(规范相关)的更多相关文章
- <<Effective Java>> 第四十三条
<<Effective Java>> 第四十三条:返回零长度的数组或者集合,而不是null 如果一个方法的返回值类型是集合或者数组 ,如果在方法内部需要返回的集合或者数组是零长 ...
- Effective.Java第45-55条(规范相关)
45. 明智谨慎地使用Stream 46. 优先考虑流中无副作用的函数 47. 优先使用Collection而不是Stream作为方法的返回类型 48. 谨慎使用流并行 49. 检查参数有效 ...
- [Effective JavaScript 笔记]第66条:使用计数器来执行并行操作
第63条建议使用工具函数downloadAllAsync接收一个URL数组并下载所有文件,结果返回一个存储了文件内容的数组,每个URL对应一个字符串.downloadAllAsync并不只有清理嵌套回 ...
- Effective java读书札记第一条之 考虑用静态工厂方法取代构造器
对于类而言,为了让client获取它自身的一个实例,最经常使用的方法就是提供一个共同拥有的构造器. 另一种放你发,也应该子每一个程序猿的工具箱中占有一席之地.类能够提供一个共同拥有的静态 工厂方法.它 ...
- <<Effective Java>>之善用组合而不是继承
使用JAVA这门OO语言,第一要义就是,如果类不是专门设计来用于被继承的就尽量不要使用继承而应该使用组合 从上图2看,我们的类B复写了类A的add喝addALL方法,目的是每次调用的时候,我们就能统计 ...
- Java异常(二) 《Effective Java》中关于异常处理的几条建议
概要 本章是从<Effective Java>摘录整理出来的关于异常处理的几条建议.内容包括:第1条: 只针对不正常的情况才使用异常第2条: 对于可恢复的条件使用被检查的异常,对于程序错误 ...
- 阅读《Effective Java》每条tips的理解和总结(1)
<Effective Java>这本书的结构是90来条tips,有长有短,每条tip都值的学习.这里根据对书中每条tip的理解做简短的总结,方便日后回顾.持续更新~ 1. 考虑用静态方法代 ...
- Effective Java 学习笔记之第七条——避免使用终结(finalizer)方法
避免使用终结方法(finalizer) 终结方法(finalizer)通常是不可预测的,也是很危险的,一般情况下是不必要的. 不要把finalizer当成C++中析构函数的对应物.java中,当对象不 ...
- Effective Java通俗理解(下)
Effective Java通俗理解(上) 第31条:用实例域代替序数 枚举类型有一个ordinal方法,它范围该常量的序数从0开始,不建议使用这个方法,因为这不能很好地对枚举进行维护,正确应该是利用 ...
随机推荐
- English--元音
English|元音 在一开始学习英语的时候,最需要掌握的就是音标.所以需要从音标的元音开始,并且不局限于掌握音标的元音与辅音,大家可以参考下英文版发音课,并不知道只学习元音与辅音,还有各种弱读连读等 ...
- fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC
出现如下错误: fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires ...
- 常用SQL语句分享
前言: 日常工作或学习过程中,我们可能会经常用到某些SQL,建议大家多多整理记录下这些常用的SQL,这样后续用到会方便很多.笔者在工作及学习过程中也整理了下个人常用的SQL,现在分享给你!可能有些S ...
- Odoo field字段标签属性详解
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826356.html 标签属性 1) name:标识字段名称 2)string:标签文本,如果我们想要覆盖 ...
- POJ3070 斐波那契数列递推 矩阵快速幂模板题
题目分析: 对于给出的n,求出斐波那契数列第n项的最后4为数,当n很大的时候,普通的递推会超时,这里介绍用矩阵快速幂解决当递推次数很大时的结果,这里矩阵已经给出,直接计算即可 #include< ...
- jq node.js bootstrap
1.node.js 网址:https://nodejs.org/en/ 用来通过下载node.js 来引用里面的npm 来实现对外部项目的下载 1.安装nodejs 自带了npm npm instal ...
- String s = new String("xyz");创建了几个String Object?并作说明。
String s = new String("xyz");创建了几个String Object?并作说明. 共产生了两个2个对象,第一个是字符串常量xyz,存储于常量池中.第二个对 ...
- USACO Cow Frisbee Team
洛谷 P2946 [USACO09MAR]牛飞盘队Cow Frisbee Team 洛谷传送门 JDOJ 2632: USACO 2009 Mar Silver 2.Cow Frisbee Team ...
- Selenium请求库
阅读目录 一 介绍 二 安装 三 基本使用 四 等待元素被加载 五 选择器 六 元素交互操作 七 其他 八 项目练习 九 破解登录验证 一 介绍 1.selenium是什么? selenium最初是一 ...
- Vue Echarts 饼图设置默认选中一个
Vue Echarts 饼图设置默认选中一个 myChart.setOption(data) // data伟echarts所需要传入的参数,就是配置参数最多的那个玩意 myChart.dispatc ...