仅记录自己学习过,且有一定自我理解和思考的
考虑使用静态工厂方法替代构造方法
优点
有名字
不需要每次调用时创建对象,例:Boolean.valueOf(?)
可以返回其返回类型的任何子类型的对象,例:Collections.unmodifiableCollection(?)
返回对象的类,可以根据输入参数的不同而不同,例:EnumSet.noneOf(?)
编写包含该方法的类时,返回的对象的类不需要存在,例:ServiceLoader.load(?)
缺点
当构造方法参数过多时使用builder模式
优点
- 解决参数过多问题
- 可以对参数间依赖关系进行校验
- 去掉创建对象时的中间状态
- 可以不暴露类中的set方法,使其变成不可变对象
缺点
- 创建对象前必须先创建它的builder
- 代码比较复杂,4个以上参数才适用
实例
简单情况下可以直接使用@Builder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @Getter public final class Student {
private final String id; private final String name;
private Student(StudentBuilder studentBuilder){ this.id = studentBuilder.id; this.name = studentBuilder.name; } public static Student.StudentBuilder builder(){ return new Student.StudentBuilder(); } @Setter @Accessors(fluent = true,chain = true) protected static class StudentBuilder{
private String id; private String name;
public StudentBuilder() { }
public Student build(){ if(!StringUtils.hasText(name)){ throw new IllegalArgumentException("name not support empty"); } return new Student(this); } } }
Student student = Student.builder() .id("001") .name("张三") .build();
|
实现 Singleton 属性
私有构造方法
饿汉式(类加载时创建)
1 2 3 4 5 6 7 8 9 10 11 12
| public class LogGenerator {
private static final LogGenerator LOG_GENERATOR = new LogGenerator();
private LogGenerator(){ }
public static LogGenerator getInstance(){ return LOG_GENERATOR; }
}
|
类加载的时候创建,如果类的初始化时间较长,可以将其初始化过程暴露在程序启动时。
懒汉式(第一次使用时创建)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class LogGenerator {
private volatile static LogGenerator LOG_GENERATOR;
private LogGenerator(){ }
public static LogGenerator getInstance(){ if(LOG_GENERATOR == null){ synchronized (LogGenerator.class){ if(LOG_GENERATOR == null){ return new LogGenerator(); } } } return LOG_GENERATOR; }
}
|
null判断后加锁再判断:只判断一次,线程并发会出现问题
volatile:防止指令重排序,初始化对象分为三步:1.分配内存 2.调用构造函数初始化对象 3.将初始化对象的地址放在分配内存里。其中第3步可能被重排序在第2步前,此时分配内存已不为null,但是还未初始化对象,使用对象会出现问题。
静态内部类
1 2 3 4 5 6 7 8 9 10 11 12
| public class LogGenerator { private LogGenerator(){ }
public static LogGenerator getInstance(){ return LogGeneratorHolder.LOG_GENERATOR; }
private static class LogGeneratorHolder{ private static LogGenerator LOG_GENERATOR = new LogGenerator(); } }
|
由JVM保证线程安全,同时实现了懒加载
枚类
天然线程安全