《Effective Java》 读书笔记(持续更新)

2.1 用静态工厂方法代替构造器

静态工厂方法:

不通过 new (如:Date date = new Date();) 而是用一个静态方法来对外提供自身实例的方法叫做静态工厂方法(Static factory method)(如:Integer number = Integer.valueOf("3");)[new 的作用是 在用 new 构造一个新的类实例时 是告诉 JVM JVM 自动在内存中开辟一个空间 调用构造函数初始化成员变量 最终引用返回给调用方]

静态工厂方法和构造器不同的优势:

1.它们有名称

2.不必要每次创建的时候都新创建一个对象(省内存)

3.可以返回原返回类型的任何子类型的对象(里式替换)

4.所返回对象的类可以随着每次调用而发生变化 取决于静态工厂方法的参数值

5.方法返回的对象所属的类在编写包含该静态工厂方法的类时可以不存在(如:Map mp = new HashMap<>();)

静态工厂的缺点:

1.类如果不含有共有的或受保护的构造器 就不能被子类化

2.难以发现

  静态方法惯用名称:

    from:类型转换方法 只有单个参数返回是一个对应的实例 Date d = Date.from(instant); // Date 转化为时间戳

    of:聚合方法 Set faceCards = EnumSet.of(JACK, QUEEN, KING);

    valueof:一种替代方法 BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);

2.2遇到多个构造器参数时要考虑使用构造器

重叠构造器模式可行 但是当有许多参数的时候 客户端代码会很难编写 && 难以阅读 可以使用 JavaBean 模式 先调用一个无参构造器来创建对象 然后再调用 setter 方法设置必要参数

JavaBean 可能处于不一致的状态 所以它把类做成不可变是不可能的 这样对于线程安全就要额外作出努力 

解决办法是可以用 Builder 模式 Builder 模式模拟了具名的可选参数 Builder 模式也适用于类层次结构 

即:如果类的构造器或者静态工厂中具有多个参数 设计这种类时 Builder 模式就是一种不错的选择

2.3用私有构造器或者枚举类型铅华 Singleton 属性

Singleton:是指仅仅被实例化一次的类 通常代表一个无状态的对象 (使类成为 Singleton 会使它的客户端测试很困难) 单元素的枚举类型经常成为实现 Singleton 的最佳方法

看完段想到的在平时用到这个的就是 Enum 了吧

package com.xxx.xx.xx.enums;

public enum NameListTypeEnum {
    BLACKNAMELIST("1", "黑名单"),
    WHITENAMELIST("2", "白名单"),
    GRAYNAMELIST("3", "灰名单");

    private String code;
    private String name;

    NameListTypeEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }

    public static boolean validateCode(String code) {
        for (NameListTypeEnum nameListTypeEnum : values()) {
            if (nameListTypeEnum.getCode().equals(code)) return true;
        }
        return false;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
View Code

2.4通过私有构造器强化不可实例化的能力

通过将一些工具类做成抽象类强制该类不可被实例化是行不通的 解决办法是让该类包含一个私有构造器 这样就不会被实例化

public class UtilityClass {
    public UtilityClass() {
        throw new AssertionError();
    }
} 
View Code

useful java utility class

2.5优先考虑依赖注入来引用资源

静态工具类和 Singleton 不适合于需要引用底层资源的类 当创建一个新的实例时 就将该资源传到构造器中 (这是依赖注入的一种形式)

2.6避免创建不必要的对象

自动装箱(另一种创建多余对象的方法)使得基本类型和装箱基本类型之间的差别变得模糊起来 但是没有完全消除 要优先使用基本类型而不是装箱基本类型 要当心无意识的自动装箱

2.7消除过期对象的引用

内存泄漏的来源:1.自己管理内存不当造成内存泄漏;2.缓存;3.监听器和其他回调

2.8避免使用终结方法和清除方法

终结方法通常是不可预测的 也是很危险的 一般情况是不必要的;清除方法没有终结方法那么危险但仍然是不可预测的 运行缓慢 一般情况也是不必要的 注重时间的任务不该由终结方法或者清除方法来完成

转载于:https://www.cnblogs.com/zlrrrr/p/11311854.html

你可能感兴趣的:(java)