4. 经过个人构造器强化不可实例化的力量,4. 透过个人构造器强化不可实例化的能力

1. 设想用静态工厂方法代替构造器

静态方法的
优势

  1. 闻名称,便于明白
  2. 永不每一回都制造一个新目标
  3. 可以回来类型的其余子类型对象
  4. 创办参数化类型实例的时候,代码越发简明

缺点

  1. 类如果不含有共有或者受保证的构造器,就不可能被子类化
  2. 不如外人静态方法无不相同

1. 考虑用静态工厂方法代替构造器

静态方法的
优势

  1. 有名称,便于了然
  2. 永不每一趟都创建一个新目的
  3. 可以回到类型的此外子类型对象
  4. 创造参数化类型实例的时候,代码尤其简明

缺点

  1. 类假设不带有共有或者受保险的构造器,就不可能被子类化
  2. 不如旁人静态方法无分裂

2. 遇到多个构造器时要考虑用创设器

2. 相见两个构造器时要考虑用营造器

3. 用个人构造器或者枚举类型强化Singleton属性

  • 枚举类达成其实简单了private类型的构造函数
  • 枚举类的域(field)其实是呼应的enum类型的一个实例对象
//Define what the singleton must do.
public interface MySingleton {
    public void doSomething();
}
private enum Singleton implements MySingleton {
    /**
     * The one and only instance of the singleton.
     *
     * By definition as an enum there MUST be only one of these and it is inherently thread-safe.
     */
    INSTANCE {
                @Override
                public void doSomething() {
                    // What it does.
                }
            };
}
public static MySingleton getInstance() {
    return Singleton.INSTANCE;
}

https://stackoverflow.com/questions/23721115/singleton-pattern-using-enum-version

3. 用个人构造器或者枚举类型强化Singleton属性

  • 枚举类已毕其实简单了private类型的构造函数
  • 枚举类的域(field)其实是呼应的enum类型的一个实例对象
//Define what the singleton must do.
public interface MySingleton {
    public void doSomething();
}
private enum Singleton implements MySingleton {
    /**
     * The one and only instance of the singleton.
     *
     * By definition as an enum there MUST be only one of these and it is inherently thread-safe.
     */
    INSTANCE {
                @Override
                public void doSomething() {
                    // What it does.
                }
            };
}
public static MySingleton getInstance() {
    return Singleton.INSTANCE;
}

https://stackoverflow.com/questions/23721115/singleton-pattern-using-enum-version

4. 透过个人构造器强化不可实例化的力量

4. 经过个人构造器强化不可实例化的力量

5. 防止创制不须求的目的

5. 防止创立不要求的目的

6. 拔除过期的靶子引用

6. 去掉过期的目的引用

7. 幸免使用 finalizer 方法

7. 防止接纳 finalizer 方法

8. 重写 equals 时请坚守通用约定

8. 重写 equals 时请坚守通用约定

9. 重写 equals 时总要重写 hashCode

9. 重写 equals 时总要重写 hashCode

10. 平昔重写 toString

10. 始终重写 toString

11. 小心翼翼重写 clone

11. 严俊重写 clone

12. 设想已毕 Comparable 接口

12. 考虑完毕 Comparable 接口

13. 使类和成员的可访问性最小化

13. 使类和成员的可访问性最小化

14. 在共有类中动用访问方法而非共有域

使用getter setter 方法

14. 在共有类中应用访问方法而非共有域

使用getter setter 方法

15. 使可变性最小化

每个实例中隐含的所有信息都必须在创立该实例的时候就提供,并在目的的全体生命周期(lifetime)內固定不变

15. 使可变性最小化

每个实例中隐含的有着信息都必须在开创该实例的时候就提供,并在目的的整套生命周期(lifetime)內固定不变

16. 契合优先于继续

继承打破了封装性

16. 顺应优先于继续

后续打破了封装性

17. 或者为继承而布署,并提供文档表达,要么就禁止继续

17. 或者为继续而规划,并提供文档表达,要么就禁止继续

18. 接口优于抽象类

幸存的类能够很简单被更新,以促成新的接口
接口时定义mixin(混合类型) 的精美选用
接口允许大家协会非层次接口的花色框架

18. 接口优于抽象类

现有的类可以很简单被更新,以贯彻新的接口
接口时定义mixin(混合类型) 的不错选取
接口允许我们协会非层次接口的档次框架

19. 接口只用于定义类型

常量接口不满意次口径,常量接口是对接口的不好使用

19. 接口只用于定义类型

常量接口不满意次口径,常量接口是对接口的不佳使用

20. 类层次优于标签类

20. 类层次优于标签类

21. 用函数对象表示策略

21. 用函数对象表示策略

22. 先行考虑静态成员类

嵌套类(nested class)

  • 静态成员类
  • 非静态成员类
  • 匿名类
  • 局部类

而外第一种外 其他三种被称呼内部类

22. 优先考虑静态成员类

嵌套类(nested class)

  • 静态成员类
  • 非静态成员类
  • 匿名类
  • 局部类

除却第一种外 其余两种被称作内部类

23. 请不要在新代码中行使原生态项目

23. 请不要在新代码中使用原生态类型

24. 清除非受检警告

24. 解除非受检警告

25. 列表优先于数组

数组与泛型相比,数组是协变的(covariant)、具体化的(reified)

25. 列表优先于数组

数组与泛型相比较,数组是协变的(covariant)、具体化的(reified)

26. 优先考虑泛型

26. 先期考虑泛型

27. 先行考虑泛型方法

27. 优先考虑泛型方法

28. 应用有限制通配符来提高API的称心如意

28. 选择有限制通配符来进步API的八面后珑

29. 先期考虑类型安全的异构容器

29. 事先考虑类型安全的异构容器

30. 用 enum 代替 int 常量

枚举天生就不可变

30. 用 enum 代替 int 常量

枚举天生就不可变

31. 用实例域代替序数

不要按照枚举的序数导出与涉及的值,而是要将它保存在一个实例域

public enum Ensemble {
  SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUINTET(5),
  SEXTET(6), ETPTET(7), OCTET(8), DOUBLE_QUARTET(8)

  private final int numberOfMusicians;
  Ensemble(int size) { this.numberOfMusicians = size; }
  public int numberOfMusicians() { return numberOfMusicians; }
}

31. 用实例域代替序数

决不按照枚举的序数导出与关系的值,而是要将它保存在一个实例域

public enum Ensemble {
  SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUINTET(5),
  SEXTET(6), ETPTET(7), OCTET(8), DOUBLE_QUARTET(8)

  private final int numberOfMusicians;
  Ensemble(int size) { this.numberOfMusicians = size; }
  public int numberOfMusicians() { return numberOfMusicians; }
}

32. 用 EnumSet 代替位域

位域(bit field) 用OR位运算将多少个常量合并到一个集结中

32. 用 EnumSet 代替位域

位域(bit field) 用OR位运算将多少个常量合并到一个相会中

33. 用 EnumMap 代替序数索引

33. 用 EnumMap 代替序数索引

34. 用接口模拟可伸缩的枚举

34. 用接口模拟可伸缩的枚举

35. 诠释优先于命有名的模特式

35. 诠释优先于命有名的模特式

36. 坚韧不拔使用 Override 注脚

36. 坚称选拔 Override 评释

37. 用标记接口定义类型

标志接口 (marker interface)
没有包涵方法注脚的接口,而只是指贝因美(Beingmate)(Nutrilon)个类完成了所有某种属性的接口

37. 用标记接口定义类型

标记接口 (marker interface)
没有包涵方法申明的接口,而只是指Bellamy个类落成了颇具某种属性的接口

38. 检查参数的有效性

38. 检查参数的管用

39. 少不了时展开爱护醒拷贝

39. 不可或缺时开展爱抚醒拷贝

40. 严刻设计方法签名

  • 当心地挑选格局的称号
  • 毫无过度追求提供便民的办法
  • 防止过长的参数列表

40. 兢兢业业设计方法签名

  • 严酷地选拔形式的称谓
  • 毫无过度追求提供有益的方法
  • 幸免过长的参数列表

41. 慎用重载

41. 慎用重载

42. 慎用可变参数

42. 慎用可变参数

43. 赶回零长度的数组或者聚众,而不是null

43. 回来零长度的数组或者聚众,而不是null

44. 为持有导出的API元素编写文档注释

44. 为保有导出的API元素编写文档注释

45. 将一些变量的效用域最小化

  • 用到在注解
  • 宣称时都应当包罗一个初步化表达式

45. 将有些变量的作用域最小化

  • 用到在申明
  • 宣示时都应当包涵一个开首化表明式

46. for-each 循环优先于传统的 for 循环

46. for-each 巡回优先于传统的 for 循环

47. 打探和接纳类库

47. 叩问和行使类库

48. 只要急需规范的答案,请防止使用 float 和 double

利用 BigDecimal、int、long 举行货币统计

48. 比方急需规范的答案,请防止采用 float 和 double

选择 BigDecimal、int、long 举办货币总结

49. 主导类型优先于装箱基本项目

49. 大旨类型优先于装箱基本项目

50. 一旦其余类型更适于,则尽量防止使用字符串

  • 字符串不相符代替其余的值类型
  • 字符串不吻合代替枚举类型
  • 字符串不切合代替聚集类型
  • 字符串也不符合代替能力表 (capabilities)

50. 若是其余种类更确切,则尽量幸免使用字符串

  • 字符串不相符代替其余的值类型
  • 字符串不吻合代替枚举类型
  • 字符串不切合代替聚集类型
  • 字符串也不相符代替能力表 (capabilities)

51. 小心字符串连接的特性

51. 不容忽视字符串连接的属性

52. 经过接口引用对象

// good
List<Subscriber> subscribers = new Vector<Subscriber>()
// bad
Vector<Subscriber> subscribers = new Vector<Subscriber>()

52. 由此接口引用对象

// good
List<Subscriber> subscribers = new Vector<Subscriber>()
// bad
Vector<Subscriber> subscribers = new Vector<Subscriber>()

53. 接口优先于反射机制

反射的坏处

  • 丧失了编译时类型检查的利益
  • 执行反射访问所急需的代码蠢笨和冗长
  • 质量损失

53. 接口优先于反射机制

反射的害处

  • 错失了编译时类型检查的补益
  • 实践反射访问所需要的代码愚昧和冗长
  • 品质损失

54. 战战兢兢地使用当地点法

Java Native Interface (JNI) 允许调用本地点法(native method)

54. 小心翼翼地行使当地方法

Java Native Interface (JNI) 允许调用本地点法(native method)

55. 如履薄冰的拓展优化

55. 严苛的进行优化

56. 死守普遍接受的命名惯例

56. 遵从普遍接受的命名惯例

57. 只针对十分的意况才使用至极

57. 只针对卓殊的事态才使用极度

58. 对可复原的状态采纳受检非常,对编程错误采纳运行时卓殊

两种可抛出荒谬(throwable)

  • 受检的可怜(checked exception) 希望调用者能适用地东山再起
  • 运行时更加 (runtime exception) 前提违例 (precondition violation)
  • 错误(error)

58. 对可复原的事态接纳受检很是,对编程错误选择运行时那么些

三种可抛出荒谬(throwable)

  • 受检的要命(checked exception) 希望调用者能确切地还原
  • 运行时尤其 (runtime exception) 前提违例 (precondition violation)
  • 错误(error)

59. 幸免不要求地使用受检的越发

59. 避免不要求地选择受检的不胜

60. 先期使用正式的丰裕

60. 事先采纳标准的那多少个

61. 抛出与虚无相对应的可怜

61. 抛出与指雁为羹相呼应的分外

62. 各种方法抛出的越发都要有文档

62. 各样方法抛出的不胜都要有文档

63. 在细节音讯中蕴藏能捕获战败的信息

63. 在细节音讯中富含能捕获败北的音信

64. 使劲使战败保持原子性

挫折方法调用应该使对象有限支撑在被调用从前的景况

64. 尽力使失败保持原子性

未果方法调用应该使对象有限襄助在被调用此前的气象

65. 不要忽视至极

65. 不用大意万分

66. 合办访问共享的可变数据

66. 同步访问共享的可变数据

67. 幸免过度同步

67. 防止过度同步

68. executor 和 task 优先于线程

68. executor 和 task 优先于线程

69. 油但是生工具优先于wait 和 notify

69. 冒出工具优先于wait 和 notify

70. 线程安全性的文档化

70. 线程安全性的文档化

71. 慎用延迟初阶化

71. 慎用延迟开头化

72. 不用借助线程调度器

72. 并非借助线程调度器

73. 幸免使用线程组

73. 避免使用线程组

74. 谨慎地落实 Serializable 接口

74. 谨慎地完结 Serializable 接口

75. 考虑动用自定义系列化格局

75. 考虑使用自定义种类化形式

76. 敬重性地编写 readObject 方法

76. 爱戴性地编写 readObject 方法

77. 对此实例控制,枚举类型优先于 readResolve

77. 对此实例控制,枚举类型优先于 readResolve

78. 考虑用连串化代理代替系列化实例

为可种类化的类设计一个私有的静态嵌套类,精确地代表外围类的实例的逻辑状态。那么些嵌套类被称作系列化代理(serialization
proxy)

78. 考虑用连串化代理代替体系化实例

为可体系化的类设计一个民用的静态嵌套类,精确地表示外围类的实例的逻辑状态。那些嵌套类被称作系列化代理(serialization
proxy)