好处

  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. DuckDuckGo Privacy Browse‪r‬

    DuckDuckGo Privacy Browser https://apps.apple.com/app/duckduckgo-privacy-browser/id663592361 https:/ ...

  2. npm config set registry

    npm config set registry $ npm config set registry $ npm config set registry https://registry.your-re ...

  3. 高阶类 & HOC & anonymous class extends

    高阶类 & HOC & anonymous class extends js 匿名 class extends / mix-ins / 多继承 高阶函数 HOF, 接收一个 funct ...

  4. TypeScript 4.0 New Features

    TypeScript 4.0 New Features $ npm install typescript@beta https://devblogs.microsoft.com/typescript/ ...

  5. input support upload excel only

    input support upload excel only demo https://codepen.io/xgqfrms/pen/vYONpLB <!-- <input placeh ...

  6. clisp的一些function

    ;; example: (write (A-Z :start (+ 65 1) :end 87)) (defmacro A-Z (&key (start 65) (end 90)) (let* ...

  7. BGV币与YFI币、YFII币存在着怎样的相关性?

    大多数的玩家并没有长期的打算,而是更倾向于关注短期利好的币种.比如最近在圈内赚足眼球的YFI,之所以能够成为明星角色,并非它的技术和平台,而是因为它在短期就创造了86倍的暴涨.YFI币的暴涨在某种程度 ...

  8. js如何判断一假则假,全真则真

    思路:初始化flag参数为true,一旦有一个为假,则将flag赋值为false,最后返回. 代码如下: checkSupplyWt(list){ var flag = true; list.forE ...

  9. 微信小程序开发小技巧:

    小技巧:输入view.tabs_content就可以生成下面的代码. 输入p10,就可以得到: 输入jc:c得到:文字水平对齐 输入d:f得到: 输入ai:c得到: 输入bb得到: currentCo ...

  10. Java流程控制:循环结构

    一.简介 顺序结构的程序语句只能被执行一次,如果您想要同样的操作执行多次,就需要使用循环结构. Java中有三种主要的循环结构: 'while'循环 'do...while'循环 'for'循环 在J ...