Effective Java – Item 1 静态工厂

本文探讨了静态工厂方法的概念,对比了其与构造器的区别,并详细分析了它的优缺点。介绍了静态工厂方法在Java中的实际应用案例,如Integer.valueOf(int)等,并解释了它如何提高程序的空间和时间效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

item1 · 静态工厂

静态工厂不是设计模式中的工厂方法

例子

public static Boolean valueOf(boolean b) {
    return b ? Boolean.TRUE : Boolean.FALSE;
}

优点

  • 静态工厂有名字

        /**
         * Constructs a newly allocated {@code Integer} object that
         * represents the specified {@code int} value.
         *
         * @param   value   the value to be represented by the
         *                  {@code Integer} object.
         *
         * @deprecated
         * It is rarely appropriate to use this constructor. The static factory
         * {@link #valueOf(int)} is generally a better choice, as it is
         * likely to yield significantly better space and time performance.
         */
        @Deprecated(since="9")
        public Integer(int value) {
            this.value = value;
        }
    
    • 使用 Integer.valueOf(123) 比使用 new Integer(123) 更为直观
    • 源代码中的更好的空间和时间可以见 Integer.vauleOf(int) 的实现(参见下一条)
        /**
         * Returns an {@code Integer} instance representing the specified
         * {@code int} value.  If a new {@code Integer} instance is not
         * required, this method should generally be used in preference to
         * the constructor {@link #Integer(int)}, as this method is likely
         * to yield significantly better space and time performance by
         * caching frequently requested values.
         *
         * This method will always cache values in the range -128 to 127,
         * inclusive, and may cache other values outside of this range.
         *
         * @param  i an {@code int} value.
         * @return an {@code Integer} instance representing {@code i}.
         * @since  1.5
         */
        @HotSpotIntrinsicCandidate
        public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    
  • 不必每次调用都创建一个新对象

    • Boolean 示例中 valueOf 无需每次创建新对象,因为只存在两种情况
    • Integer.valueOf(int) 中使用的 IntegerCache 对值为 -128~127 的 Integer 对象进行缓存
      Integer a = 1000, b = 1000;  
      System.out.println(a == b); // false  
      Integer c = 100, d = 100;  
      System.out.println(c == d); // true
    
  • 可以返回原返回类型的任何子类型对象

    interface Parent {
        static Parent getChild1(){
                return new Child1();
        }
        static Parent getChild2(){
            return new Child2();
        }
    }
    
    class Child1 implements Parent {}
    class Child2 implements Parent {}
    
    • Java 8 之后可以支持接口有静态方法(如上)
    • 另一例:Java Collections Framework 有45个工具实现,分别提供了不可修改的集合、同步集合,等等。
  • 随每次调用而发生变化

    interface Parent {
        static Parent getChild(int i) {
            return i == 1 ? new Child1() : new Child2();
        }
    }
    
    class Child1 implements Parent {}
    class Child2 implements Parent {}
    
  • 返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在

    • 服务提供者框架的基础
    • 例:JDBC
      • 服务接口(Service Interface) Connection
      • 提供者注册API (Provider Registration API) DriverManager.registerDriver
      • 服务访问API(Service Access API) DriverManager.getConnection
      • 不同数据库的 Connection 的具体实现是不一样的,通过 registerDriver 注册数据库的连接方法到JDBC上,通过 getConnection 获得可以使用的 Connection

缺点

  • 类如果不包含公有的或者受保护的构造器,就不能被子类实例化

    public class Collections {
        // Suppresses default constructor, ensuring non-instantiability.
        private Collections() {
        }
    }
    
  • 不容易识别出静态工厂

    • 在API文档中没有像构造器那样明确标识出来

    • 通过在类或者接口注释中关注静态工厂,并遵守标准的命名习惯

      • from —— 类型转换方法

        Date d = Date.from(instant);
        
      • of —— 聚合方法,带有多个参数

        Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING);
        
      • valueOf —— 比 from 和 of 更封锁的一种替代方法

        BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
        
        
      • instance 或 getInstance —— 返回的实例时通过方法的(如有)参数来描述的,但是不能说与参数具有同样的值

        StackWalker luke = StackWalker.getInstance(options);
        
        
      • create 或 newInstance —— 像instance或者getInstance一样,区别在于每次调用都返回一个新的实例

        Object newArray = Array.newInstance(classObject, arrayLen);
        
        
      • getType —— 像getInstance一样,但是在工厂方法处于不同的类中的时候使用。Type表示工厂方法所返回的对象类型

        FileStore fs = Files.getFileStore(path);
        
        
      • newType —— 像newInstance一样,但是在工厂方法处于不同的类中的时候使用

        BufferedReader br = Files.newBufferedReader(path);
        
        
      • type —— getType和newType的简版

        List<Complaint> litany = Collections.list(legacyLitany);
        
        
基于数据挖掘的音乐推荐系统设计与实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐与其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐与其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
MPU6050是一款广泛应用在无人机、机器人和运动设备中的六轴姿态传感器,它集成了三轴陀螺仪和三轴加速度计。这款传感器能够实时监测并提供设备的角速度和线性加速度数据,对于理解物体的动态运动状态至关重要。在Arduino平台上,通过特定的库文件可以方便地与MPU6050进行通信,获取并解析传感器数据。 `MPU6050.cpp`和`MPU6050.h`是Arduino库的关键组成部分。`MPU6050.h`是头文件,包含了定义传感器接口和函数声明。它定义了`MPU6050`,该包含了初始化传感器、读取数据等方法。例如,`begin()`函数用于设置传感器的工作模式和I2C地址,`getAcceleration()`和`getGyroscope()`则分别用于获取加速度和角速度数据。 在Arduino项目中,首先需要包含`MPU6050.h`头文件,然后创建`MPU6050`对象,并调用`begin()`函数初始化传感器。之后,可以通过循环调用`getAcceleration()`和`getGyroscope()`来不断更新传感器读数。为了处理这些原始数据,通常还需要进行校准和滤波,以消除噪声和漂移。 I2C通信协议是MPU6050与Arduino交互的基础,它是一种低引脚数的串行通信协议,允许多个设备共享一对数据线。Arduino板上的Wire库提供了I2C通信的底层支持,使得用户无需深入了解通信细节,就能方便地与MPU6050交互。 MPU6050传感器的数据包括加速度(X、Y、Z轴)和角速度(同为X、Y、Z轴)。加速度数据可以用来计算物体的静态位置和动态运动,而角速度数据则能反映物体转动的速度。结合这两个数据,可以进一步计算出物体的姿态(如角度和角速度变化)。 在嵌入式开发领域,特别是使用STM32微控制器时,也可以找到似的库来驱动MPU6050。STM32通常具有更强大的处理能力和更多的GPIO口,可以实现更复杂的控制算法。然而,基本的传感器操作流程和数据处理原理与Arduino平台相似。 在实际应用中,除了基本的传感器读取,还可能涉及到温度补偿、低功耗模式设置、DMP(数字运动处理器)功能的利用等高级特性。DMP可以帮助处理传感器数据,实现更高级的运动估计,减轻主控制器的计算负担。 MPU6050是一个强大的六轴传感器,广泛应用于各种需要实时运动追踪的项目中。通过 Arduino 或 STM32 的库文件,开发者可以轻松地与传感器交互,获取并处理数据,实现各种创新应用。博客和其他开源资源是学习和解决问题的重要途径,通过这些资源,开发者可以获得关于MPU6050的详细信息和实践指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值