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条(规范相关)的更多相关文章

  1. <<Effective Java>> 第四十三条

    <<Effective Java>> 第四十三条:返回零长度的数组或者集合,而不是null 如果一个方法的返回值类型是集合或者数组 ,如果在方法内部需要返回的集合或者数组是零长 ...

  2. Effective.Java第45-55条(规范相关)

    45.  明智谨慎地使用Stream 46.  优先考虑流中无副作用的函数 47.  优先使用Collection而不是Stream作为方法的返回类型 48.  谨慎使用流并行 49.  检查参数有效 ...

  3. [Effective JavaScript 笔记]第66条:使用计数器来执行并行操作

    第63条建议使用工具函数downloadAllAsync接收一个URL数组并下载所有文件,结果返回一个存储了文件内容的数组,每个URL对应一个字符串.downloadAllAsync并不只有清理嵌套回 ...

  4. Effective java读书札记第一条之 考虑用静态工厂方法取代构造器

    对于类而言,为了让client获取它自身的一个实例,最经常使用的方法就是提供一个共同拥有的构造器. 另一种放你发,也应该子每一个程序猿的工具箱中占有一席之地.类能够提供一个共同拥有的静态 工厂方法.它 ...

  5. <<Effective Java>>之善用组合而不是继承

    使用JAVA这门OO语言,第一要义就是,如果类不是专门设计来用于被继承的就尽量不要使用继承而应该使用组合 从上图2看,我们的类B复写了类A的add喝addALL方法,目的是每次调用的时候,我们就能统计 ...

  6. Java异常(二) 《Effective Java》中关于异常处理的几条建议

    概要 本章是从<Effective Java>摘录整理出来的关于异常处理的几条建议.内容包括:第1条: 只针对不正常的情况才使用异常第2条: 对于可恢复的条件使用被检查的异常,对于程序错误 ...

  7. 阅读《Effective Java》每条tips的理解和总结(1)

    <Effective Java>这本书的结构是90来条tips,有长有短,每条tip都值的学习.这里根据对书中每条tip的理解做简短的总结,方便日后回顾.持续更新~ 1. 考虑用静态方法代 ...

  8. Effective Java 学习笔记之第七条——避免使用终结(finalizer)方法

    避免使用终结方法(finalizer) 终结方法(finalizer)通常是不可预测的,也是很危险的,一般情况下是不必要的. 不要把finalizer当成C++中析构函数的对应物.java中,当对象不 ...

  9. Effective Java通俗理解(下)

    Effective Java通俗理解(上) 第31条:用实例域代替序数 枚举类型有一个ordinal方法,它范围该常量的序数从0开始,不建议使用这个方法,因为这不能很好地对枚举进行维护,正确应该是利用 ...

随机推荐

  1. 完整且易读的最新版小程序登录态和检验注册过没的app.js写法

    目录 0.可参考的官方页面 1.流程 2.app.js代码 3.java后台怎么通过code获取openId 0.可参考的官方页面 获取登录凭证:https://developers.weixin.q ...

  2. 2.redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发?

    作者:中华石杉 面试题 redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发? 面试官心理分析 这个是问 redis 的时候,最基本的 ...

  3. MySQL数据库(三)--表相关操作(二)之约束条件、关联关系、复制表

    一.约束条件  1.何为约束 除了数据类型以外额外添加的约束 2.约束条件的作用 为了保证数据的合法性,完整性 3.主要的约束条件 NOT NULL # 标识该字段不能为空,默认NULL,可设置NOT ...

  4. XGBoost使用教程(与sklearn一起使用)二

    一.导入必要的工具包# 运行 xgboost安装包中的示例程序from xgboost import XGBClassifier # 加载LibSVM格式数据模块from sklearn.datase ...

  5. 【转载】QQ炫舞手游自制谱子教程(星动模式)

    第一步:计算ET和BPM: 抄送原作者部落链接:https://buluo.qq.com/p/detail.html?bid=368006&pid=981862-1529828677& ...

  6. nginx访问jupyter

    现在jupyter已通过k8s安装完成,并通过nodeport暴露出来. 如果不能直接访问这个nodeport(像我在的公司)或是希望能组织好jupyter实例, 那应该如何调通呢? 这里包括两个技术 ...

  7. xcode运行demo报错:Failed to create provisioning profile.cannot be registered to your development team

    问题:网上下载运行demo,出现Failed to create provisioning profile.cannot be registered to your development team此 ...

  8. python字典中显示中文

    #coding=utf-8import jsondict={'title':"这是中文"}print json.dumps(dict,ensure_ascii=False,enco ...

  9. LIST OF BEST OPEN SOURCE BLOCKCHAIN PLATFORMS

    https://www.blockchain-council.org/blockchain/list-of-best-open-source-blockchain-platforms/ Open so ...

  10. docker自定义镜像上传阿里云

    1.alpine制作jdk镜像 2.Alpine制作jre镜像(瘦身) 3.Docker镜像上传至阿里云 alpine制作jdk镜像 alpine Linux简介 1.Alpine Linux是一个轻 ...