Fork me on GitHub

创建和销毁对象

最近一直加班,好久没看书学习了。今天开始学习Effective Java(第二版),从第二章开始,第二章名字为创建和销毁对象。

第一条:考虑用静态工厂方法代替构造器

对于类而言,获取实例的方法,是提供公有的构造器,还有一种方法就是提供一个公有的静态工厂方法,它本身只是一个获取实例的静态方法。
例子:
public static Boolean valueOf(boolean b){
  return b ? Boolean.TRUE : Boolean.FALSE;
}

优点:

  1. 静态工厂方法与构造器不同的第一大优势是,它们有名称。
  2. 静态工厂方法与构造器不同的第二大优势是,不必在每次调用它们的时候都创建一个新对象。这对于操作实例受控的类很有帮助,实例受控的类指单例模式类或不可实例化类。
  3. 静态工厂方法与构造器不同的第三大优势是,它们可以返回原返回类型的任何子类型的对象。

缺点:

  1. 如果不包含公有的或者受保护的构造器,就不能被子类化。这点毋庸置疑,继承的话,需要调用父类构造器。鼓励使用复合,而不是继承。
  2. 它们本质上是静态方法,与其它静态方法实际上并没有本质区别。

下面列举一些标准的命名习惯:

  • valueOf,该方法返回的实例与它的参数具有相同的值,本质上是类型转换方法。
  • getInstance,返回的实例是通过方法的参数来描述的,但是不能够说与参数具有同样的值。对于Singleton来说,该方法没有参数,并返回唯一的实例。
  • newInstance,与getInstance相似,但newInstance能够确保返回的每个实例都与所有其它实例不同。
  • getType,与getInstance类似,但是在工厂方法处于不同的类中的时候使用,Type表示工厂方法所返回的对象类型。
  • newType,同newInstance类似,但是在工厂方法处于不同的类中的时候使用,Type表示工厂方法所返回的对象类型。

第二条:遇到多个构造器参数时要考虑用构建器

静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数。例如用一个类来表示包装食品外面显示的营养成分标签。
package test;

public class Person {
    private String IDCard;
    private String name;
    private int age;
    private double tall;
    private double weight;
    private String address;
    
    public Person(Builder builder){
        this.IDCard = builder.IDCard;
        this.name = builder.name;
        this.age = builder.age;
        this.tall = builder.tall;
        this.weight = builder.weight;
        this.address = builder.address;
    }
    
    @Override
    public String toString() {
        return "Person [IDCard=" + IDCard + ", name=" + name + ", age=" + age
                + ", tall=" + tall + ", weight=" + weight + ", address="
                + address + "]";
    }

    public static class Builder{
        //必填属性
        private String IDCard;
        private String name;
        //可选属性
        private int age;
        private double tall;
        private double weight;
        private String address;
        public Builder(String IDCard,String name){
            this.IDCard = IDCard;
            this.name = name;
        }
        public Builder age(int age){
            this.age = age;
            return this;
        }
        public Builder tall(double tall){
            this.tall = tall;
            return this;
        }
        public Builder weight(double weight){
            this.weight = weight;
            return this;
        }
        public Builder address(String address){
            this.address = address;
            return this;
        }
        public Person build(){
            return new Person(this);
        }
    }
}
如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder模式就是种不错的选择,特别是当大多数参数都是可选的时候。与使用传统的重叠构造器模式相比,使用Builder模式更易于阅读和编写,构建器也比JavaBeans更安全。

第三条:用私有构造器或者枚举类型强化Singleton属性

第四条:通过私有构造器强化不可实例化的能力

第五条:避免创建不必要的对象

第六条:消除过期的对象引用

第七条:避免使用终结方法

 
posted @ 2018-11-21 19:51  爱跑步的星仔  阅读(172)  评论(0编辑  收藏  举报