0    重要

0.1  核心

通常情况,创建对象考虑用静态工厂方法代替构造器

 

0.2  需要掌握的东西

0.2.1  静态工厂的缺点:

  • 类如果不含公有的或者受保护的构造器,就不能被子类化

这个很好理解,如果类不含上述的这两种构造器,当然就没办法被继承。但实际这样或许也是一个好处,因为这样能鼓励程序员使用复合,而不是继承,这正是不可变类型所需要的。

参考:https://blog.csdn.net/weixin_42522009/article/details/114103361

  • 程序员很难发现静态工厂方法

因为静态工厂方法是自定义的,它们没有像构造器那样被明确规定如何实例化,因此程序员往往很难查明如何通过静态工厂方法实例化一个类,因此我们便需要遵守一些静态工厂方法的惯用名称。

解决该问题的方法见0.2.2

 

 

0.2.2  如何区分静态工厂方法和其他静态方法

通过方法名区分,使用约定熟成的静态方法名:

类型转换:from,valueOf,of

获取或创建该类:getInstance,newInstance,getType(参考2.3),newType,type,create等

详细的可以参考这篇

 

https://blog.csdn.net/a517865058/article/details/104829478

 

1    内容

1.0  静态工厂方法定义

Fragment fragment = new MyFragment();
// or
Date date = new Date();


然而实际中是这样:
Fragment fragment = MyFragment.newIntance();
// or 
Calendar calendar = Calendar.getInstance();
// or 
Integer number = Integer.valueOf("3");
像上面这样的:不通过 new,而是用一个静态方法来对外提供自身实例的方法,即为我们所说的静态工厂方法。

参考:https://blog.csdn.net/weixin_44148815/article/details/87653744

 

1.1  静态工厂方法与构造器相比的优点

  • 静态工厂方法有名称,便于阅读

如BigInteger的判断质数的方法,通过名称可能为质数,方便理解

    public static BigInteger probablePrime(int var0, Random var1) {
        if (var0 < 2) {
            throw new ArithmeticException("bitLength < 2");
        } else {
            return var0 < 95 ? smallPrime(var0, 100, var1) : largePrime(var0, 100, var1);
        }
    }

 

  • 不必再每次调用它们的时候都创建一个新的对象,节省了开销
  • 静态工厂方法可以返回原类型的任何子类型的对象

如下:java.util.Collections 有如下方法

    public static <T> ArrayList<T> list(Enumeration<T> var0) {
        ArrayList var1 = new ArrayList();

        while(var0.hasMoreElements()) {
            var1.add(var0.nextElement());
        }

        return var1;
    }


    public static <T> Set<T> unmodifiableSet(Set<? extends T> var0) {
        return new Collections.UnmodifiableSet(var0);
    }

上边代码直接从源码拿到,最好参考右侧网址,便于理解:https://blog.csdn.net/u014519120/article/details/78741481

 

  • 创建参数化类型实例时,代码更加简洁(参考泛型的使用)

 

1.2  静态工厂方法与构造器相比的缺点

见0.2.1

 

2    代码演练

2.1  静态工厂方法demo

静态工厂类:

package com.ddwei.test.core.chapter1;

public class CreateObject {


    /***
     * 静态工厂方法
     * @author weidoudou
     * @date 2022/4/11 7:25
     * @param b 请添加参数描述
     * @return java.lang.Boolean
     **/
    public static Boolean valueOf(boolean b){
        return b ? Boolean.TRUE : Boolean.FALSE;
    }

}

 

测试类:

package com.ddwei.test.core.chapter1;

import com.alibaba.fastjson.JSON;

public class CreateObjectTest {
    public static void main(String[] args) {
        Boolean b = CreateObject.valueOf(true);
        System.out.println(JSON.toJSONString(b.hashCode()));
    }
}

 

日志:

1231

Process finished with exit code 0

 

 

2.2  不含公有或受保护的构造器,不能被子类化demo

父类:

package com.ddwei.test.core.chapter1.demo12;

public class FatherDemo {
    private int age;

    private FatherDemo(){
    }
}

 

子类:

 

2.3  getType的使用demo1

静态工厂1

package com.ddwei.test.core.chapter1.demo13;

public class SpringFactory {
    /**
     *蝴蝶春天有翅膀
     * @author weidoudou
     * @date 2022/4/12 7:09
     * @param
     * @return com.ddwei.test.core.chapter1.demo13.ButterFly
     **/
    public static ButterFly getButterFly(){
        ButterFly butterFly = new ButterFly();
        butterFly.setHaveWing(true);
        return butterFly;
    }

}

 

静态工厂2

package com.ddwei.test.core.chapter1.demo13;

public class WinterFactory {

    /**
     * 蝴蝶冬天无翅膀
     * @author weidoudou
     * @date 2022/4/12 7:09
     * @param
     * @return com.ddwei.test.core.chapter1.demo13.ButterFly
     **/
    public static ButterFly getButterFly(){
        ButterFly butterFly = new ButterFly();
        butterFly.setHaveWing(false);
        return butterFly;
    }
}

 

实体类:

package com.ddwei.test.core.chapter1.demo13;

import lombok.Setter;

@Setter
public class ButterFly {
    /**
     * 是否有翅膀
     */
    private boolean haveWing;


}

 

2.4  getType的使用demo2

package com.ddwei.test.core.chapter1.demo13;

import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class StaticDemo {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("D:/wdd");
        FileStore fs= Files.getFileStore(path);
    }
}

 

posted on 2022-02-09 06:59  菜鸟乙  阅读(44)  评论(0编辑  收藏  举报