【Effective Java】第4章 读书笔记

2021/6/14 14:20:53

本文主要是介绍【Effective Java】第4章 读书笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

第4章 类和接口

15,使类和成员可访问性最小化

尽可能地使每个类或者成员不能被外界访问。

公有类的实例域绝不能是公有的。

包含公有可变域的类通常并不是线程安全的。

让类具有公有的静态 final 数组域,或者这种域的访问方法是错误的。

16,要在公有类中使用访问方法而非公有域

公有类永远都不要暴露可变的的域

17,使可变性最小化

不可变类是指实例不可以被修改的类

17.1 不可变类要遵循的五条原则:

  1. 不要提供任何可以修改对象状态的方法。
  2. 保证类不会被扩展。
  3. 声明所有的域都是 final 的。
  4. 声明所有的域都是私有的
  5. 确保对于任何可变组件的互斥访问。

17.2 不可变对象的优缺点:

  1. 不可变对象本质上是线程安全的,它们不要求同步。
  2. 不可变对象可以被自由的共享。
  3. 不仅可以共享不可变对象,甚至可以共享它们的内部信息。
  4. 不可变对象为其它对象提供了大量构件。
  5. 不可变对象无偿地提供了失败的原子性(详见76条)。
  6. 不可变对象唯一的缺点是对于每个不同的值都需要一个单独的对象。

如果类不能做成不可变的,仍然应尽可能地限制它的可变性

除非有令人信服地理由要使域变成是非 final 的,否则要使每个域都是 private final 的

构造器应该创建完全初始化对象,并建立所有约束关系

18,复合优于继承(类继承)

越包继承是非常危险的。

与方法调用不同的是,继承打破了封装性

复合:不扩展现有的类,而是在新的类中增加一个私有域,它引用现有类的一个实例。

19,要么设计继承并提供文档说明,要么禁止继承

该类必须有文档说明它可覆盖的方法和自用性

可覆盖的方法:非 final 的,公有的或者受保护的。

对于为了继承而设计的类,唯一的测试方法是编写子类,发布之前必须对子类就那些测试。

构造器绝不能调用可被覆盖的方法。

无论是 clone 还是 readObject,都不可以调用可覆盖的方法。

为了继承而设计类,对这个类会有一些实质性的限制。

20,接口优于抽象类

现有的类可以很容易被更新,以实现新的接口。

接口是定义mixin(混合类型)的理想选择,而抽象类不行。

接口允许构造非层次结构的类型框架。

接口使得更安全地增强类功能成为了可能。

通过对接口实现一个抽象的骨架实现类可以把接口和抽象类地优点结合起来(好的文档是非常必要i的!)

接口负责定义类型,或许还提供一些缺省方法(default method),而骨架实现类负责实现 基本类型的方法和非基本类型接口方法。拓展骨架实现占了实现接之外的大部分工作。这就是模板方法模式。

骨架实现类被称为 AbstractInterface,例如集合框架中的 AbstractSet,AbstractList,AbstractMap。

21,为后代设计接口

JDK8 之后:缺省方法(default method)

  • 缺省方法的声明中包括一个缺省实现(default implementation)。
  • 并非每一个可以实现的所有变体,始终都可以编写以个缺省方法。例如:removeIf。
  • 有了缺省方法,接口的现有实现就不会出现编译时没有报错或警告,运行时却失败的情况。
  • 尽管缺省方法现在已经是Java平台的组成部分,但是谨慎设计接口仍然是至关重要的。

22,接口只用于定义类型

常量接口是对接口的不良使用。

接口只用来定义类型,不应该被用来导出常量。

23,类层次优于标签类

类层次:通过继承连接起来做类似的事情。

标签类:两种甚至更多风格的实例的类,并包含表示实例风格的标签域。

标签类过于冗长,容易出错,且效率低下。

24,静态成员类优于非静态成员类

嵌套类:内部类。

外围类:内部类的外围的类。

嵌套类有4种:

  • 静态成员类

  • 非静态成员类

  • 匿名类

  • 局部类

如果声明成员类不要求访问外围实例,就要始终把修饰符static放在它的声明种。

25,限制源文件为单个顶级类

顶级类:最外层,没有继承的类。

  • 如果一个源文件中定义多个顶级类,可能会导致给一个类提供多个定义。哪一个定义会被用到,取决于源文件传输给编译器的顺序。

  • 如果一定要把多个顶级类放入一个源文件,就要考虑使用静态成员类,以此代替将这两个类分到独立的源文件中去。

结论:

永远不要把多个顶级类或者接口放入一个源文件中。遵循这个原则可以确保编译时一个类不会有多个定义。这么做反过来也能确保编译产生的类文件,以及程序结果行为都不会受到源文件传给编译器的顺序的影响。



这篇关于【Effective Java】第4章 读书笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程