【Effective Java 01】 创建和销毁对象 —— 用静态工厂方法代替构造器

  • 静态工厂方法的优点:
    1. 有名称,提升代码可读性
    2. 不必每次调用都创建新对象
    3. 可以返回原类型的任何子类对象
    4. 返回的对象的类可以随每次调用而发生变化,可以取决于静态工厂的方法参数
    5. 方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在。(例如JDBC API 中的服务提供者框架)
  • 静态工厂方法的缺点:
    1. 类如果不含共有的或者受保护的构造器,则不能被子类化
    2. 程序员难以发现

DEMO 代码

import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.*;

public class StaticFactoryDemo {

    public static void main(String[] args) throws IOException {
        // JDK 中常见的静态工厂方法;
        /*
         * 1. from -- 类型转换方法, 只有单个参数, 返回该类型的一个相对应的实例
         */
        Instant instant = Instant.now();
        Date date = Date.from(instant);
        System.out.println("date:" + date);

        /*
         * 2. of -- 聚合方法, 带有多个参数, 返回该类型的一个实例, 把他们合起来
         */
        Set<Card> faceCards = EnumSet.of(Card.CARD_J, Card.CARD_Q, Card.CARD_K);
        System.out.println("faceCards:" + faceCards);

        /*
         * 3. valueOf -- 比 from 合 of 更繁琐的一种替代方法
         */
        BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
        System.out.println("prime:" + prime);

        /*
         * 4. instance 或者 getInstance -- 返回实例是通过方法的(如有)参数来描述的, 但不能说与参数具有相同的值
         */
        StackWalker luke = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);

        /*
         * 5. create 或者 newInstance -- 确保每次调用都会返回一个新的实例
         */
        Object newArray = Array.newInstance(Integer.class, 16);

        /*
         * 6. get[Type] -- 像 getInstance 一样, 但是在工厂方法处于不同的类中的时候使用. Type 表示工厂方法返回的对象类型的名称
         */
        Path path = Paths.get("./");
        FileStore fileStore = Files.getFileStore(path); // 返回对象类型为 FileStore
        System.out.println("fileStore:" + fileStore);
        /*
         * 7. new[Type] -- 像 newInstance 一样, 但是在工厂方法处于不同的类中的时候使用, Type 表示工厂方法所返回的对象类型, 例如:
         */
        BufferedReader bufferedReader = Files.newBufferedReader(path);

        /*
         * 7. [type] -- getType 和 newType 的简版, 例如:
         */
        Enumeration<String> days;
        Vector<String> dayNames = new Vector<>(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"));
        days = dayNames.elements();
        List<String> list = Collections.list(days);
        System.out.println("list:" + list);
    }
}

posted on 2022-03-09 21:14  Silgm  阅读(38)  评论(0)    收藏  举报

导航