好处

  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 驱动框架---驱动中的时间相关

    内核中的时间 Linux 系统内核对于时间的管理依赖于硬件,硬件按一定的周期产生中断,周期由内核的一个配置值HZ决定在系统启动时会将定时器配置为HZ值指定的频率产生中断:同时内核和维护一个64位(X8 ...

  2. GPU 加速 & WebGL

    GPU 加速 & WebGL 开启 GPU 加速, 硬件加速 垃圾面试官,瞎忽悠 holy shit 美国想象力英语,前端 leader WebGL 加速 ??? 是什么鬼 ??? three ...

  3. how to convert Map to Object in js

    how to convert Map to Object in js Map to Object just using the ES6 ways Object.fromEntries const lo ...

  4. pure CSS waterfall layout

    pure CSS waterfall layout 纯 CSS 瀑布流布局 flex layout .container{} .item{} https://caniuse.com/?search=c ...

  5. NGK每日快讯」2021.1.27日NGK公链第85期官方快讯!

  6. NGK:APP一站式挖矿高收益项目

    NGK是10月中旬刚上线的公链项目,采用手机挖矿形式.NGK数字增益平台,200美金即可入场,收益可观,分为静态和动态两种,投资算力收益超高.邀请好友挖矿还有额外的返佣. NGK立志为所有人创造无差别 ...

  7. 阿里面试这样问:redis 为什么把简单的字符串设计成 SDS?

    2021开工第一天,就有小伙伴私信我,还给我分享了一道他面阿里的redis题(这家伙绝比已经拿到年终奖了),我看了以后觉得挺有意思,题目很简单,是那种典型的似懂非懂,常常容易被大家忽略的问题.这里整理 ...

  8. Java并发包源码学习系列:同步组件CyclicBarrier源码解析

    目录 CyclicBarrier概述 案例学习 类图结构及重要字段 内部类Generation及相关方法 void reset() void breakBarrier() void nextGener ...

  9. eclipse自定义快捷键

    eclipse系统自带的快捷键设置有时候使用起来并不习惯,可以自定义某些常用的快捷键. 依次打开 Window->Preference->General->Keys,这里显示了所有的 ...

  10. 如何吃透Python的面向对象(OOP)

    ​本篇可乐和大家一起来吃透 Python 的面向对象,类和实例. 面向对象(OOP) 解释:面向对象它是一种编程的思想,将现实事物抽象化为编程对象. 举例说明:喝可乐 ① 选择自己根据配方买对应的材料 ...