如何高效的创建对象

简介: 不禁思考,以后怎样避免这样的问题。难道以后想创建某些对象,都得点进去看下源码,看下构造器是如何处理的?当然没必要,我们其实可以有更好的方案——静态工厂方法。

引子

事情是这样的,今天写了单元测试下一个hsf服务,查一下最近一个月的数据

@Test
public void testServiceList(){
    ActivityDTO dto = new ActivityDTO();
    activity.setStartDate(new Date(2022, 3, 1, 0, 0, 0));
    activity.setEndDate(new Date(2022, 3, 31 0, 0, 0));
    // 最近一个月的数据肯定是有的,结果发现什么都没查到...
    List<Activity> list = activityService.list(dto);
}

没多久就定位问题了,打开了Date的构造方法查看源码,不经吐槽:

我以为构造出的年月日,你却做了这么多处理,往后推迟了1900年1个月!怪不得落得“过时”的下场。

@Deprecated
public Date(int year, int month, int date, int hrs, int min, int sec) {
    int y = year + 1900;
    // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
    if (month >= 12) {
        y += month / 12;
        month %= 12;
    } else if (month < 0) {
        y += CalendarUtils.floorDivide(month, 12);
        month = CalendarUtils.mod(month, 12);
    }
    BaseCalendar cal = getCalendarSystem(y);
    cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
    cdate.setNormalizedDate(y, month + 1, date).setTimeOfDay(hrs, min, sec, 0);
    getTimeImpl();
    cdate = null;
}

不禁思考,以后怎样避免这样的问题。

难道以后想创建某些对象,都得点进去看下源码,看下构造器是如何处理的?

当然没必要,我们其实可以有更好的方案——静态工厂方法。

下面我们就通过几个典型例子认识下它的优点:

静态工厂方法

1. 方法名称即可表达创建对象的含义
LocalDateTime now = LocalDateTime.now();
LocalDateTime localDateTime = LocalDateTime.of(2022, 3, 1, 0, 0, 0);

// 构造器表意不明
new Date();
new Date(2022, 3, 1, 0, 0, 0);
2. 不一定要创建新的对象
// 当值在low,high 之间时,如Integer.valueOf(1)是没有创建新的Integer对象,而是取的缓存
public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
}
3. 可以返回原类型的任何子类型对象
// 构造方法只能返回确切的自身类型,而静态工厂方法则能够更加灵活,可以根据需要方便地返回任何它的子类型的实例
// (Collections)SingletonList是私有内部类,extends AbstractList<E>
public static <T> List<T> singletonList(T o) {
     return new SingletonList<>(o);
}
// EmptyList是私有内部类,extends AbstractList<E>
public static final <T> List<T> emptyList() {
     return (List<T>) EMPTY_LIST;
}
4. 减少对外暴露不必要的属性
public class Company {
    public static final int TYPE_TECHNOLOGY = 1;
    public static final int TYPE_INTELLIGENT = 2;
    public static final int TYPE_INTERNATIONAL = 3;
    int type;

    /**
     * 限制外部创建非定义对象
     * 如:new Company(4)
     */
    private Company(int type) {
        this.type = type;
    }

    public static Company newTechnology() {
        return new Company(TYPE_TECHNOLOGY);
    }

    public static Company newIntelligent () {
        return new Company(TYPE_INTELLIGENT);
    }

    public static Company newInternational() {
        return new Company(TYPE_INTERNATIONAL);
    }
}

简而言之,创建对象优先使用工厂方法,这个可以减少调用者出错的机率;

类的提供者对入口的改造和构造方法的限制,可以让更加有效的控制类。

正如《Effective Java》建议:考虑使用静态工厂方法代替构造器

相关文章
|
14天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
6天前
|
云安全 人工智能 安全
Dify平台集成阿里云AI安全护栏,构建AI Runtime安全防线
阿里云 AI 安全护栏加入Dify平台,打造可信赖的 AI
|
9天前
|
人工智能 运维 Java
Spring AI Alibaba Admin 开源!以数据为中心的 Agent 开发平台
Spring AI Alibaba Admin 正式发布!一站式实现 Prompt 管理、动态热更新、评测集构建、自动化评估与全链路可观测,助力企业高效构建可信赖的 AI Agent 应用。开源共建,现已上线!
845 25
|
8天前
|
机器学习/深度学习 人工智能 搜索推荐
万字长文深度解析最新Deep Research技术:前沿架构、核心技术与未来展望
近期发生了什么自 2025 年 2 月 OpenAI 正式发布Deep Research以来,深度研究/深度搜索(Deep Research / Deep Search)正在成为信息检索与知识工作的全新范式:系统以多步推理驱动大规模联网检索、跨源证据。
578 46
|
2天前
|
监控 BI 数据库
打工人救星!来看看这两家企业如何用Quick BI让业务更高效
Quick BI专业版监控告警助力企业高效运作,通过灵活配置规则与多渠道推送,让数据异常早发现、快响应,推动业务敏捷决策与持续增长。
打工人救星!来看看这两家企业如何用Quick BI让业务更高效
|
8天前
|
人工智能 Java Nacos
基于 Spring AI Alibaba + Nacos 的分布式 Multi-Agent 构建指南
本文将针对 Spring AI Alibaba + Nacos 的分布式多智能体构建方案展开介绍,同时结合 Demo 说明快速开发方法与实际效果。
563 42