《Effective Java》阅读笔记-第九章

Effective Java 阅读笔记

第九章 通用编程

第 57 条 将局部变量的作用域最小化

将局部变量的作用域最小化,可以增强代码的可读性和可维护性,并降低出错的可能。

  • 将局部变量的作用域最小化,最好的办法就是在第一次使用变量的地方声明它。
  • 几乎每一个局部变量都应该进行初始化。

第 58 条 for-each 循环优先于传统 for 循环

for-each(又称增强 for 循环)隐藏了迭代器和索引变量,避免了出错的可能(特别是嵌套循环时)。

但是下面集中情况无法使用 for-each 循环:

  • 解构、过滤:如果需要删除集合种特定元素,就需要使用迭代器,并调用remove方法,或者使用 Java 8 的removeIf方法。
  • 转换:如果需要下标对特定元素进行处理,就只能使用普通循环。
  • 并行迭代:如果需要同时迭代两个循环(特别是嵌套时),就需要操作下标,并进行手动控制迭代。

第 59 条 了解并使用类库

使用类库比自己造轮子更靠谱。比如 Java 7 之后生成随机数就不要使用 Random 类,使用 ThreadLocalRamdom 类,新类更快并且线程安全。

第 60 条 如果需要非常精确的答案,不要使用 float 或者 double

浮点数是不够精确的,不适合用来进行金融计算。

BigDecimal来代替 double。如果有最小单位时,可以使用 int 或者 long 进行计算,性能更好,并且也非常精确(但是除法就不行了)。

第 61 条 基本类型优先于装箱类型

基本类型更节省空间,并且计算速度更快(因为不用去堆中创建空间);

自动拆装箱减少了基本类型的烦琐性,但是并没有减少风险。
自动拆箱时,如果包装类型是null,就会抛出空指针异常。

第 62 条 如果其他类型合适,尽量避免使用字符串

字符串更容易出错,并且通常性能也更低。能使用其他类型的时候,尽量使用其他类型。

第 63 条 了解字符串连接的性能

使用+可以很方便的拼接字符串,但是会有性能问题。虽然 Java 8 之后反编译加号拼接其实还是StringBuilder,但是有些情况下会大量创建 StringBuilder对象,导致性能下降。

因此在拼接字符串时可以手动创建 StringBuilder 然后使用 append 方法进行拼接。大多数时候,相对加号拼接而言都是更快的。

第 64 条 通过接口引用对象

第 51 条有:使用接口作为参数,而不是使用类。更确切的来说,是使用接口来引用对象,而不是用类来引用。

如果有合适的接口类型存在,那么参数、返回值、变量、字段等都应该使用接口来声明。

如果养成了使用接口作为类型的习惯,程序会更加灵活。

在没有合适的接口时,完全可以使用类来引用对象(这不废话吗)。更准确的说,是如果没有合适的接口,就用类层次中提供了必要功能的最小具体类来引用对象。

第 65 条 接口优先于反射机制

反射允许在运行时访问给定义一个 Class 的构造器、方法、字段等,非常灵活,但是也有以下缺点:

  • 损失了编译时的类型检查:如果用反射调用不存在的方法,会发生运行时异常。
  • 执行反射访问所需要的代码非常笨拙、冗长:反射代码非常乏味,并且阅读起来也很困难。
  • 性能损失:反射比起直接调用要慢了不少。

如果有限制的使用反射,虽然也有部分代价,但是也有非常多的好处。

许多程序必须用到的类在编译时是不可用的,但是有适当的接口或者超类可以引用这个类,如果是这种情况,就可以通过反射创建实例,然后通过接口或者超类进行引用,然后正常调用。
这样性能比Method.invoke要好。

第 66 条 谨慎地使用本地方法

使用本地方法来提高性能的做法不值得提倡。因为 Java 越来越快了,并且标准库中已经提供了大部分需要的实现。

第 67 条 谨慎地进行优化

  • 不要为了性能编牺牲合理的结构,要努力编写好的程序而不是快的程序。
  • 要努力避免性质性能的设计。
  • 要考虑 API 设计的性能后果。
  • 为了获得好的性能而对 API 进行包装是一种非常不好的想法。
  • 尝试优化的前后,要做出性能对比。

第 68 条 遵循普遍接受的命名惯例

每种语言一般都有各自推荐的命名方式,Java 也不例外:

标识符或类型 示例
包或者模块 org.junit.jupiter.api, com.google.common.collect
类或者接口 Stream, FutureTask, LinkedHashMap, HttpClient
方法或者字段 remove, groupBy, getCrc
常量 MIN_VALUE, HEGATIVE_INFINITY
局部变量 i, denom, houseNum
泛型 T, E, K, V, X, R, U, T1, T2
posted @ 2024-02-21 16:17  code-blog  阅读(2)  评论(0编辑  收藏  举报