Effective第三版 中英 | 第二章 创建和销毁对象 | 通过私有构造器强化不可实例化的能力

news2024/11/25 11:48:58

文章目录

  • Effective第三版
    • 前言
    • 第二章 创建和销毁对象
      • 通过私有构造器强化不可实例化的能力

Effective第三版

前言

大家好,这里是 Rocky 编程日记 ,喜欢后端架构及中间件源码,目前正在阅读 effective-java 书籍。同时也把自己学习该书时的笔记,代码分享出来,供大家学习交流,如若笔记中有不对的地方,那一定是当时我的理解还不够,希望你能及时提出。如果对于该笔记存在很多疑惑,欢迎和我交流讨论,最后也感谢您的阅读,点赞,关注,收藏~

前人述备矣,我只是知识的搬运工,effective 书籍源码均在开源项目 java-diary 中的 code-effective-third 模块中

源代码仓库地址: https://gitee.com/Rocky-BCRJ/java-diary.git

第二章 创建和销毁对象

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

在这里插入图片描述

  Occasionally you’ll want to write a class that is just a grouping of static methods and static fields. Such classes have acquired a bad reputation because some people abuse them to avoid thinking in terms of objects, but they do have valid uses. They can be used to group related methods on primitive values or arrays, in the manner of java.lang.Math or java.util.Arrays. They can also be used to group static methods, including factories (Item 1), for objects that implement some interface, in the manner of java.util.Collections. (As of Java 8, you can also put such methods in the interface, assuming it’s yours to modify.) Lastly, such classes can be used to group methods on a final class, since you can’t put them in a subclass.

  有时候你会想要编写一个只包含一组静态方法和静态字段的类。这种类名声很不好,因为有些人为了避免使用面向对象的思维方式而滥用这样的类(some people abuse them to avoid thinking in terms of objects),但是他们确实有它们特有的用处。我们可以使用这种类,以java.lang.Math或者java.util.Arrays的方式对原始值或数组的相关方法组织起来。它们还可以用于以java.util.Collections的方式,把实现特定接口的对象上的静态方法(包括工厂:第 1 项)组织起来。(从 Java 8 开始,你也可以将这些方法放在接口中,假设它是你自己修改的)。最后,这些类可以用于将final类的方法组织起来,通过这种方式用来取代扩展该类的做法。

  Such utility classes were not designed to be instantiated: an instance would be nonsensical. In the absence of explicit constructors, however, the compiler provides a public, parameterless default constructor. To a user, this constructor is indistinguishable from any other. It is not uncommon to see unintentionally instantiable classes in published APIs.

  这种工具类不希望被实例化,实例化对它没有任何意义。然而,在没有显式构造函数的情况下,编译器会默认提供一个公共的、无参的默认构造函数。对于用户而言,这个构造器与其他构造器没有任何区别。在已发行的 API 中常常可以看到一些被无意识地实例化的类。

  Attempting to enforce noninstantiability by making a class abstract does not work.The class can be subclassed and the subclass instantiated. Furthermore, it misleads the user into thinking the class was designed for inheritance (Item 19). There is, however, a simple idiom to ensure noninstantiability. A default constructor is generated only if a class contains no explicit constructors, so a class can be made noninstantiable by including a private constructor:

  企图通过将该类做成抽象类来强制该类不可被实例化,这是行不通的。该类可以被子类化,并且该子类也可以被实例化。这样做甚至会误导用户,以为这种类是专门为了继承而设计的(第 19 项)。然而,有一些简单的习惯用法可以确保类不可被实例化。由于只有当类不包含显示的构造器时,编译器才会生成缺省的构造器,因此我们只要让这个类包含私有构造器,他就不能被实例化了:

// Noninstantiable utility class
public class UtilityClass {
    // Suppress default constructor for noninstantiability
    private UtilityClass(( {
        throw new AssertionError();
    }
    ... // Remainder omitted
}

  Because the explicit constructor is private, it is inaccessible outside the class. The AssertionError isn’t strictly required, but it provides insurance in case the constructor is accidentally invoked from within the class. It guarantees the class will never be instantiated under any circumstances. This idiom is mildly counterintuitive because the constructor is provided expressly so that it cannot be invoked. It is therefore wise to include a comment, as shown earlier.

  因为显示构造函数是私有的,所以它在类外是不可访问的,AssertionError不是必需的,但是它可以避免不小心在类的内部调用构造器。它保证该类在任何情况下都不会实例化。这种习惯用法有点违背直觉,好像构造器就是专门设计成不能被调用一样。因此明智的做法就是在代码中增加一条注释,如上所示。

  As a side effect, this idiom also prevents the class from being subclassed. All constructors must invoke a superclass constructor, explicitly or implicitly, and a subclass would have no accessible superclass constructor to invoke.

  这种习惯用法也有副作用,它使得一个类不能拥有子类。因为子类的所有构造函数都必须显示或者隐式地调用父类的构造函数,在这种情形下,子类就没有可用的并且可以访问的父类构造器了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/621944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文本三剑客 之 grep

目录 一.grep 1.grep常用选项命令选项 2.grep 命令选项 3.简单的正则表达式 二.sort 命令 三.uniq 去重 四 .语法格式: tr 选项 参数 五.快速裁剪命令——cut: 六.split 文件拆分 七.文件合并——paste 一.grep 文本三剑客了之一,对文本内容进行…

网络通信 --- HTTP 协议初识

目录 🌲一、HTTP 协议是什么 🌳二、HTTP协议格式 🦪1.抓包工具的使用(以 Fiddler 为例) 🍣2. 抓包工具的原理 (以 Fiddler 为例) 🍤3. 抓包结果 🍥① HTTP 请求(request) 🥮②HTTP响应(re…

chatgpt赋能python:Python中的平均值如何计算?

Python中的平均值如何计算? 在Python编程中,求取列表、元组或数据集合的平均值是一个相当常见的操作。幸运的是,Python内置的统计模块提供了方便的方法去实现这个操作。在这篇文章里,我们将探讨计算平均值的方法,帮助…

Unity制作二次元卡通渲染角色材质——5、脸部的特殊处理

Unity制作二次元材质角色 回到目录 大家好,我是阿赵。 这里继续讲二次元角色材质的制作。这次是讲头部的做法。 1、脸部 之前在分析资源的时候,其实已经发现了这个模型的脸部法线有问题,导致在做光照模型的时候,脸部很奇怪。 把f…

阅读ConcurrentHashMap源码,我学到了什么?

文章目录 ConcurrentHashMap怎样保证线程安全的put元素的流程具体对于红黑树是怎样保证线程安全的如何并发安全的初始化一个数组如何统计存储元素个数的怎样进行多线程扩容的 首先说明, 本篇分析基于jdk1.8. ConcurrentHashMap怎样保证线程安全的 ConcurrentHashMap主要是通过…

Java:字符流

字符流的底层其实就是字节流。 字符流字节流字符集 结构体系: 1.特点 输入流:一次读一个字节,遇到中文时,一次读多个字节。 输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中。 2.使用场景 对于纯文本…

AI实战营第二期 笔记5——MMPretrain代码课

文章目录 摘要MMPreTrain实战安装推理 OR 使用API数据集训练与测试微调 摘要 MMPretrain 是一个全新升级的预训练开源算法框架,旨在提供各种强大的预训练主干网络, 并支持了不同的预训练策略。MMPretrain 源自著名的开源项目 MMClassification 和 MMSel…

chatgpt赋能python:Python开立方函数math:让数学计算更加简单

Python开立方函数math:让数学计算更加简单 Python作为一种高级编程语言,提供了丰富的数学计算功能,其中就包括了开立方函数math。本篇文章将详细介绍math开立方函数在Python中的使用方法及其优点。 什么是开立方函数? 开立方函…

chatgpt赋能python:Python开发BI,助力企业数据驱动决策

Python开发BI,助力企业数据驱动决策 随着企业数据规模的呈现爆炸式增长,传统的Excel等表格计算工具已经无法满足业务需求,因此,企业需要更加全面和强大的方法来进行数据分析和展示。此时,BI(全称Business …

css蓝桥杯--电影院排座位

目录 一、介绍二、准备三、⽬标四、代码五、知识点六、完成 一、介绍 随着⼈们⽣活⽔平的⽇益提升,电影院成为了越来越多的⼈休闲娱乐,周末放松的好去处。各个城市的电影院数量也随着市场的需求逐年攀升。近⽇,⼜有⼀个电影院正在做着开张前…

chatgpt赋能python:Python强制关闭程序的解决方案

Python 强制关闭程序的解决方案 在Python开发过程中,难免会遇到程序卡死,无响应等问题,这时候如果无法正常退出程序,就需要进行强制关闭。本篇文章将介绍Python强制关闭程序的几种解决方案。 方法一: 使用系统命令 在Linux或Ma…

【Java】JavaWEB核心要点总结:64

文章目录 1. TCP 和 UDP的异同2. TCP为什么要三次握手 两次不行吗3. get post put 请求方式有什么区别4. 什么是XXS攻击 如何避免5. 什么是 CSRF 攻击,如何避免 1. TCP 和 UDP的异同 TCP(Transmission Control Protocol)和UDP(Use…

typedef 和 # define 用法区别

typedef 和 # define 用法区别 前言1. 原理不同1.1 typedef int * int_ptr;与#define int_ptr int * 详细讲解 2. 功能不同3. 作用域不同 前言 博主在牛客网上看到了一道有关typedef和# define题目。发现有很多初学的小伙伴对两者的用法不是特别清楚,所以博主在这总…

python内存

在python中,一切都是对象。Python从设计之初就是一门面向对象的语言,它有一个重要的概念,即一切皆对象。 Java虽然也是面向对象编程的语言,但是血统没有Python纯正。比如Java的八种基本数据类型之一int,在持久化的时候…

HCIA-NAT

目录 NAT:网络地址转换 NAT原理: NAT转换原理图: 静态NAT 静态NAT的工作原理: 静态NAT配置命令 静态NAT配置实例: 动态NAT 动态NAT的工作原理 动态NAT: 动态NAT配置命令 动态NAT案例 NAPT NA…

css蓝桥杯--⾃适应⻚⾯

目录 一、介绍二、准备三、⽬标四、代码五、完成 一、介绍 响应式布局是在 2010 年 5 ⽉份提出的⼀个概念,这个概念是为解决移动互联⽹浏览⽽诞⽣的。简⽽⾔之,就是⼀个⽹站能够兼容多个终端——⽽不是为每个终端做⼀个特定的版本。通过响应式布局可以为…

EXCEL文本处理总结:如何查找(/定位)字符串内,符合条件的多个符号里的最后一个?

目录 题外话:学习总结 1 新手切忌贪多 2 熟练者切忌懒惰 3 这2件事恰恰都和人性相反 1 EXCEL文本处理相关函数 2 查找函数 find() 和 search() 2.1 find() 2.2 search() 2.3 下面是测试的公式情况 3 如何查找(定位)符合条件的某个字符的位置?…

MySQL触发器的使用

目录 一、前言二、触发器分类1.插入触发器2.更新触发器3.删除触发器 三、查看触发器四、异常处理五、小结 一、前言 各种主流数据库,都集成了触发器的功能。触发器提供了一种机制,允许开发者在对数据库表的插入、更新、删除的前后捕获相应的数据行。从而针对数据行实现特定的逻…

DebugView的使用

目录 一、前言二、本机调试1.DebugView程序文件说明2.OutputDebugString函数使用3.示例程序4.远程调试 三、问题与注意事项四、小结 一、前言 DebugView是windows下的一款调试工具,可以捕获程序输出的日志,分为64位和32位,支持应用层和内核层的日志捕获,利用它排除bug是个不错的…

chatgpt赋能python:Python开发手机软件的优势和挑战

Python开发手机软件的优势和挑战 随着智能手机的普及,移动应用开发已成为当前最热门的技术领域之一。随着越来越多的企业意识到移动应用的重要性,越来越多的开发者开始加入这个领域。 在移动应用的开发中,由于其高效性和易于学习的特点&…