好处

  1. 有名称,能见名知意。例如BigInteger的probablePrime方法

  2. 享元模式、单例模式中使用

享元模式:创建对象代价很高,重复调用已有对象,例如数据库连接等。享元模式是单例模式的一个拓展。

  1. 可以返回原类型的任何子类型

  2. 可以通过参数值添加业务逻辑返回不同对象,基于第3点

interface Demo {
    static Demo getDemoByParam(Integer param) {
        if (param > 0) {
            return new BigDemo();
        } else {
            return new SmallDemo();
        }
    }
}
private static class BigDemo implements Demo {
}
private static class SmallDemo implements Demo {
}
  1. 可以返回不存在的类的对象,服务提供者框架例如JDBC,java1.6java提供一个服务提供者框架 java.util.ServiceLoader(JDBC早于ServiceLoader所以没有使用它)

服务提供者框架包括:

  1. 服务者接口,提供服务的接口如JDBC的Connection接口

  2. 服务提供者接口,获取服务提供者的接口如JDBC的Driver接口,如下是mysql提供的实

 public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    static {
        try {
            //我们在使用的时候 Class.forName("com.mysql.jdbc.Driver")会加载该启动,并调用服务提供者注册API进行注册驱动
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }
    public Driver() throws SQLException {
    }
}
  1. 服务提供者注册API(DriverManager.registerDriver())

  //mysql生产厂方提供并使用它在我们加载其Driver的时候进行注册
  1. 服务访问API(DriverManager.getConnection())

  //我们可以直接,加载Driver后我们可以通过它获取服务对象Connection
 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/education5?serverTimezone=Asia/Shanghai","root","123456");

java.util.ServiceLoader方式:

//服务接口
public class Hello{
 void hello();
}

public class DemoUtils {
 //服务注册API和访问API,这里因为是demo所以卸载了一起
public static void hello(){
    ServiceLoader<Hello> load = ServiceLoader.load(Hello.class);
    for (Hello hello : load) {
        hello.hello();
    }
}
}
//服务接口实现
public class HelloImpl1 implements Hello {
@Override
public void hello() {
    System.out.println("HelloImpl1.hello");
}

public static void main(String[] args) {     //测试代码
    DemoUtils.hello();
}
}

在classpath下创建对应接口目录的文件/META-INF/services/com.demo.Hello文件注册我们写的实现类即可

com.demo.Hello文件

com.demo.HelloImpl1

缺点

  1. 不包含共有或者受保护的构造器,导致无法被继承。这样也因祸得福,鼓励程序员使用组合而不是继承。

  2. 静态工厂方法一般和类或者接口分离出来,例如Collection和Collections。如果静态工厂方法所在的类没有提供API我们就很难找到类的实例化方法了。通过类或者接口注释并遵守命名规范来弥补这一劣势如下部分,实际使用过程中可以查询或者百度

  • from——类型转换方法,单个参数,返回一个像相对应的实例

  • of——聚合方法,带有多个参数,多个实例聚合成一个实例

  • instance或者newInstance 通过方法参数创建实例(也可以没有参数)

  • create或者newInstance 通过参数方法创建实例但是每次创建一个新的实例

effective解读-第一条 静态工厂创建对象代替构造器的更多相关文章

  1. EFFECTIVE JAVA 第一天 静态工厂方法

    静态工厂方法:(这里指的是就是普通static方法),类可以通过静态工厂方法提供给它的客户端,而不是通过构造器.提供静态工厂方法而不是公有构造器,这样做有几大优势. 在类的实现中使用了API的类被称为 ...

  2. Java - 用静态工厂方法代替构造器

    Effective Item - 考虑用静态工厂方法代替构造器我们有两种常见的方法获得一个类的实例: 公有的构造器 提供静态工厂方法(static factory method) 相对公有的构造器,静 ...

  3. Effective java读书札记第一条之 考虑用静态工厂方法取代构造器

    对于类而言,为了让client获取它自身的一个实例,最经常使用的方法就是提供一个共同拥有的构造器. 另一种放你发,也应该子每一个程序猿的工具箱中占有一席之地.类能够提供一个共同拥有的静态 工厂方法.它 ...

  4. Effective Java 读书笔记(一):使用静态工厂方法代替构造器

    这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文&l ...

  5. effective java 3th item1:考虑静态工厂方法代替构造器

    传统的方式获取一个类的实例,是通过提供一个 public 构造器.这里有技巧,每一个程序员应该记住.一个类可以对外提供一个 public 的 静态工厂方法 ,该方法只是一个朴素的静态方法,不需要有太多 ...

  6. 【Effective Java读书笔记】创建和销毁对象(一):考虑使用静态工厂方法代替构造器

    类可以提供一个静态方法,返回类的一个静态实例,如Boolean包装类的一个获取实例的静态方法 public static Boolean valueOf(boolean b) { return (b ...

  7. 【读书笔记 - Effective Java】01. 考虑用静态工厂方法代替构造器

    获取类的实例有两种方法: 1. 提供一个公有的构造器(最常用). 2. 提供一个公有的静态工厂方法(static factory method). // 静态工厂方法示例 public static ...

  8. 高效JAVA之用静态工厂方法代替构造器

    程序员这行干的久了,总会染上一些恶习,我就染上一个让人深恶痛绝,自己却津津乐道的习惯,还不想改的那种,它可以叫做强迫症,也可以叫做洁癖.那就是我不允许我的IDEA出现一点点警告,什么黄色背景,绿色波浪 ...

  9. 静态工厂方法VS构造器

    我之前已经介绍过关于构建者模式(Builder Pattern)的一些内容,它是一种很有用的模式用于实例化包含几个属性(可选的)的类,带来的好处是更容易读.写及维护客户端代码.今天,我将继续介绍对象创 ...

随机推荐

  1. Linux 驱动框架---i2c驱动框架

    i2c驱动在Linux通过一个周的学习后发现i2c总线的驱动框架还是和Linux整体的驱动框架是相同的,思想并不特殊比较复杂的内容如i2c核心的内容都是内核驱动框架实现完成的,今天我们暂时只分析驱动开 ...

  2. js 可选链 & 空值合并 In Action

    js 可选链 & 空值合并 In Action const obj = { props: { name: 'eric', }, // prop, 不存在的属性 ️ }; console.log ...

  3. React Hooks: useImperativeHandle All In One

    React Hooks: useImperativeHandle All In One useImperativeHandle https://reactjs.org/docs/hooks-refer ...

  4. Linux & change username & computer name & .bashrc

    Linux & change username & computer name ubuntu change username and computer name https://ask ...

  5. how to using Linux pipe command output another command's help content to a file

    how to using Linux pipe command output another command's help content to a file Linux tee > >& ...

  6. website text select notes menu

    website text select notes menu website 文字选择笔记菜单(下划线, 标记, 复制, 分享) 下划线, 标记 https://time.geekbang.org/ ...

  7. gradient text & gradient background

    gradient text & gradient background -webkit-text-fill-color & -webkit-gradient https://wesbo ...

  8. React Hooks +React Context vs Redux

    React Hooks +React Context vs Redux https://blog.logrocket.com/use-hooks-and-context-not-react-and-r ...

  9. Captain technology INC:高性能电池助力新能源车企销量暴涨

    来自七个欧洲国家的11个合作伙伴共聚一堂,投身于HyFlow研究项目,共同开发一种可兼顾高性能和能源需求的混合氧化还原液流储能系统.为此,科学家们希望将高性能钒氧化还原液流电池与超级电容器相结合. 到 ...

  10. 如何通过NGK数字增益平台实现兑换算力

    最近币圈里有一个新项目NGK非常火热,很多朋友在经过了了解以后纷纷表示很看好这个项目,那么除了二级市场之外,是否还能有其他的方式可以更低成本地获得NGK代币呢? 答案是肯定的,NGK数字增益平台便是低 ...