• Effective Java学习笔记--创建和销毁对象


    创建和销毁对象

    一.静态工厂方法代替构造器

     静态工厂方法的优缺点

      优点:

        1.可以自定义名称(可以将功能表述的更加清晰)

        2.不必每次调用都创建新的对象(同一对象重复使用)

        3.返回的类型可以是原返回类型的任何子类型对象

        4.简化创建对象时的代码

      缺点:

        1.如果不含有公开的构造器,就不能被子类化

        2.和普通的静态方法没有区别

    二.遇到多个构造器参数时考虑用构建器

      如果我们现在需要编写一个描述客户信息的类,在客户的信息中名字是一定有的,其他的信息都是可能用,我们使用三种方法去完成:

    1.重叠构造器方法(代码已经简化)

     1 /**
     2  * 客户信息
     3  */
     4 public class Customer {
     5     private  String name;//姓名
     6     private  String profession;//职业
     7     private  int age;//年龄
     8     private  String gender;//性别
     9     
    10     public Customer(String name){
    11         this.name=name;
    12     }
    13     
    14     public Customer(String name,String profession){
    15         this.name=name;
    16         this.profession=profession;
    17     }
    18     
    19     public Customer(String name,String profession,int age){
    20         this.name=name;
    21         this.profession=profession;
    22         this.age=age;
    23     }
    24     
    25     public Customer(String name,String profession,int age,String gender){
    26         this.name=name;
    27         this.profession=profession;
    28         this.age=age;
    29         this.gender=gender;
    30     } 
    31 }

      创建实例:

    Customer customer=new Customer("李雷", "程序员", 27, "男");

      总结:这里是简化后的代码,此实例才4个参数就如此繁琐,随着参数的增加,将会失去控制。

    2.JavaBean模式(调用无参构造方法,然后用set方法赋值)

     1 /**
     2  * 客户信息
     3  */
     4 public class customer {
     5     private  String name;//姓名
     6     private  String profession;//职业
     7     private  int age;//年龄
     8     private  String gender;//性别
     9     
    10     public customer(){}
    11     
    12     public void setName(String name) {
    13         this.name = name;
    14     }
    15     
    16     public void setProfession(String profession) {
    17         this.profession = profession;
    18     }
    19     
    20     public void setAge(int age) {
    21         this.age = age;
    22     }
    23     
    24     public void setGender(String gender) {
    25         this.gender = gender;
    26     }
    27 }

      创建实例:

            customer customer=new customer();
            customer.setAge(27);
            customer.setGender("男");
            customer.setName("李雷");
            customer.setProfession("程序员");

      总结:创建实例容易,也比较容易阅读,但是由于对象的构造过程被分到了几部调用中,JavaBean可能处于不一致的状态,而且使用此模式无法将类制作成不可变的。

    3.构建器(Builder模式)

     1 /**
     2  * 客户信息
     3  */
     4 public class Customer {
     5     private final String name;//姓名
     6     private final String profession;//职业
     7     private final int age;//年龄
     8     private final String gender;//性别
     9     
    10     public static class Builder{
    11         private final String name;
    12         
    13         private String profession="无";
    14         private int age=0;
    15         private String gender="未知";
    16         
    17         public Builder(String name){
    18             this.name=name;
    19         }
    20         
    21         public Builder profession(String val){
    22             profession=val;
    23             return this;
    24         }
    25         
    26         public Builder age(int val){
    27             age=val;
    28             return this;
    29         }
    30         
    31         public Builder gender(String val){
    32             gender=val;
    33             return this;
    34         }
    35         
    36         public Customer build(){
    37             return new Customer(this);
    38         }
    39     }
    40     
    41     private Customer(Builder builder){
    42         name=builder.name;
    43         profession=builder.profession;
    44         age=builder.age;
    45         gender=builder.gender;
    46     }        
    47 }

      创建实例:

        创建对象时,类名后面加括号表示调用无参的构造函数;不加括号表示调用默认的构造函数或唯一的构造函数     
      Customer customer=new Customer.Builder("李雷").age(27).gender("男").profession("程序员").build();

      总结:编写容易,易于阅读,而且模拟了具名的可选参数,安全性高,后期的扩展性强。

    3.单元素枚举是实现Singleton的最佳方法

    1 public enum Elvis {
    2     INSTANCE;
    3     
    4     public void leaveTheBuilding(){
    5         System.out.println("Singleton!");
    6     }
    7 }

      创建实例:

            Elvis elvis=Elvis.INSTANCE;

    4.消除对其对象的引用

      下面是一个栈的简单实现:

    public class Stack {
        private Object[] elements;
        private int size=0;
        private static final int DEFAULE_INITAL_CAPACITY=16;
        
        public Stack(){
            elements=new Object[DEFAULE_INITAL_CAPACITY];
        }
        
        public void push(Object e){
            ensureCapacity();
            elements[size++]=e;
        }
        
        public Object pop(){
            if (size==0) {
                throw new EmptyStackException();
            }
            return elements[--size];
        }
        
        public void ensureCapacity(){
            if (elements.length==size) {
                elements=Arrays.copyOf(elements, 2*size+1);
            }
        }
    }

      如果一个栈显示增长,然后再收缩,那么从栈中弹出的对象将不会被当做垃圾回收,我们应该将过期的引用清空,将pop方法改动如下:

        public Object pop(){
            if (size==0) {
                throw new EmptyStackException();
            }
            elements[size]=null;
            return elements[--size];
        }

      

  • 相关阅读:
    Markdown高级使用之流程图
    Sentinel滑动窗口算法
    Markdown基础使用
    多线程学习(二)--整体简介
    MYSQL学习(三) --索引详解
    MYSQL学习(二) --MYSQL框架
    MYSQL 学习(一)--启蒙篇《MYSQL必知必会》
    数据结构学习(六) --排序
    数据结构学习(五)--查找
    数据结构学习(四)--图
  • 原文地址:https://www.cnblogs.com/yangc/p/6423668.html
Copyright © 2020-2023  润新知