销毁和创建对象
结构
具体
准则一:用静态工程方法代替构造器获取实列
1、示例
Boolean b1 = Boolean.valueOf(false);
Boolean b2 = Boolean.valueOf(false);
public class Person {
public Person(){
}
public static Person getInstance() {
return new Man();
}
// 这种方式就会让人难以察觉=
public static Person getPsdhfjd() {
return new Person();
}
}
2、优点:
1-1、可以有名称:静态工厂方法有名称,更容易使用
1-2、可重复利用:不必每次调用它们的时候都要创建一个新对象
1-3、可返回子类对象:可以返回任何子类的对象,更加灵活
1-4、可变的返回对象:返回的对象的类可以随着每次调用而发生变化,这取决于静态工程方法的参数值
1-5、可不存在返回对象的类:方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在。(服务提供者框架,JDBC-API)
3、缺点:
2-1、类如果不含公有或者受保护的构造器,就不能被子类化
2-2、很难被发现
准则二:遇到多个构造器参数时要考虑使用构建器
准则三:用私有构造器或者枚举类型强化Singleton属性
1、示例
public class Emp {
// 公有静态final成员
public static final Emp INSTANCE = new Emp();
// (下面的写法应该加解释说明)Suppress default constructor for noninstantiability
private Emp(){
throw new AssertionError();
}
}
public enum EmpEnum {
// 包含单个元素的枚举类型
// 简洁,提供序列化机制,绝对防止多次实例化,即使面对复炸的序列化或者反射的攻击。
INSTANCE;
}
2、说明
* 1、Singleton:仅仅被实例化一次的类
* 2、三种方式:
2-1、公有静态final成员
2-2、公有静态工厂方法
2-3、包含单个元素的枚举类型(单个元素的枚举类型是实现Singleton的最佳方法)
a、注意--如果Singleton必须扩展一个超类,而不是扩展Enum的时候,则不宜使用这个方法。
* 3、两种方式都需要构造器私有,但仍然可以通过反射创建,可以使用抛出异常的方式抵挡反射
准则四:通过私有构造器强化不可实列化的能力
1、示例
public class Emp {
// (下面的写法应该加解释说明)Suppress default constructor for noninstantiability
private Emp(){
throw new AssertionError();
}
}
2、说明
* 1、抽象类的子类是可 以被实例化的,所以抽象类不满足这个法则。
* 2、只包含一个私有构造器,它就不会被实例化
* 3、私有构造器抛出 throw new AssertionError();可以防止类的内部调用以及反射的调用。
* 4、为私有构造器添加注释 Suppress default constructor for nonInstantiaBility
准则五:优先考虑依赖注入来引用资源
1、示例
/**
* @program: HeadFirst
* @description: 依赖注入
* @author: jiawen.tang
**/
public class BeanUtil {
private final Person person;
public BeanUtil(Person person) {
this.person = Objects.requireNonNull(person);
}
}
/**
* @program: HeadFirst
* @description: 依赖注入-工厂方法
* @author: jiawen.tang
**/
public class BeanUtilT<T> {
private final T t;
public BeanUtilT(T t) {
this.t = Objects.requireNonNull(t);
}
public BeanUtilT(Supplier<T> supplier){
this.t = supplier.get();
}
}
2、说明
* 1、静态工具类和Singleton类不适合需要引用底层资源的类。
* 2、依赖注入形式一:当创建一个新的实例时,就将该资源传到构造器中。见BeanUtil
* 3、资源工厂与Supplier:见BeanUtilT
* 4、总结:不要用Singleton和静态工具类来实现依赖一个或多个底层资源的类,且该资源的行为会影响
* 到该类的行为,也不要直接用这个类来创建这些资源,而应该使用依赖注入,这样可以极大地提高类的灵活性、可重用性、可测试性。
*
参考资料: Effective Java.