• 创建和销毁对象:用静态工厂方法代替构造器


    后续我会陆陆续续更新《ava程序员开发手册》这一栏目的内容。大家如果觉得对自己有用就点个关注吧。

    声明

    本文主要来自于《Effective Java (中文第三版)》的读后感与总结,并加上一些我自己的理解,和查阅的资料

    示例代码

     下面先来简单看一下构造器和静态工厂方法的代码吧!

    public class Test_01 {
        /**
         * 这是公有的有参构造器
         */
        String name;
    
        public Test_01(String name){
            this.name = name;
        }
    
        /**
         * 这是公有的无参构造器
         */
        public Test_01(){
    
        }
    
        /**
         * 这是一个静态工厂方法
         */
        public static Test_01 getTest_01Obj(boolean check,String param){
            if(check){
                return new Test_01();
            }else{
                return new Test_01(param);
            }
        }
    
        /**
         * 静态工厂方法:获取一个狗的对象
         */
        public static Test_01 getDog(){
            return new Test_01("Dog");
        }
    
        /**
         * 静态工厂方法:获取一个空的对象
         */
        public static Test_01 getNull(){
            return new Test_01();
        }
    }
    
    • 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
    • 38
    • 39
    • 40
    • 41
    • 42

     这种静态工厂方法和设计模式中的静态工厂方法是不的,请不要混在一起,可以理解为构造器的封装。

    静态工厂方法的优缺点

    优点

    1. 有名字,这样可以更好的表述出某个方法具体返回的是什么样的值。比如:上面代码中的
        /**
         * 静态工厂方法:获取一个狗的对象
         */
        public static Test_01 getDog(){
            return new Test_01("Dog");
        }
    
        /**
         * 静态工厂方法:获取一个空的对象
         */
        public static Test_01 getNull(){
            return new Test_01();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

     上面举了一个比较简单的例子,参数很短,逻辑也很简单,但也能体现出你在代码中如果写getDog总比new Test_01("Dog")更明确。

    1. 可以控制构造器的滥用和实例对象的数量,我们可以把构造器改为私有的,然后就只能通过静态工厂方法获取实例对象,这样我们就可以对实例对象的创建加以控制。了解单例模式的小伙伴应该都应该很熟悉这种操作。下面是一个线程不安全的单例模式,当然想了解单例模式可以看我的另一篇文章设计模式:单例模式(懒汉模式/饿汉模式)
    public class Singleton {
        private static Singleton singleton;
    
        private Singleton(){
            System.out.println("我是一个单利对象");
        }
    
        public static Singleton getSingleton(){
            if(singleton == null){
                singleton = new Singleton();
                return singleton;
            }
            return singleton;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 它不像构造器本身只能返回对应的实例对象。静态工厂方法可以返回:原返回类型的任何子类型的对象。
       例如:Java Collections Framework 的集合接口有 45 个工具实现,分别提供了不可修改的集合、 同步集合,等等。现在的 Collections Framework API 比导出 45 个独立公有类 的那种 现方式 小得多。
    2. 静态工厂的第五大优势在于,方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在。

    这句话就不是很好理解了,意思就是说,再返回之前某个类可能是在程序运行过程中自动生成的,并且返回给你。和动态代理的实现是一个事情。

    缺点

    1. 第一点很好理解,既然没有公有或者受保护的构造器,那就意味着他不能被子类化(不能继承其他类)。
    2. 比较难以阅读,对于不了解接口的程序员来说很难弄清楚,接口实例化对象的过程。
  • 相关阅读:
    Java面向对象编程
    《安富莱嵌入式周报》第291期:分分钟设计数字芯片,单片机版JS,神经网络DSP,microPLC,FatFS升级至V0.15,微软Arm64 VS正式版发布
    YOLOv5全面解析教程①:网络结构逐行代码解读
    【软考 系统架构设计师】项目管理② 范围管理
    Docker查看容器的初始启动命令参数的常见几种方式
    react setState异步操作数据的问题
    Linux下gcc和gdb的基本使用
    企业架构LNMP学习笔记33
    AWS SAP-C02教程8-大数据和机器学习
    使用js开发一个快速打开前端项目的alfred插件
  • 原文地址:https://blog.csdn.net/Int_Xu/article/details/127749385