《Effective Java》第2章 创建和销毁对象

Android TV开发:RecyclerView焦点控制实践与优化 在Android TV应用开发中,焦点控制是提升用户体验的关键技术。不同于移动端触摸交互,TV端通过遥控器方向键导航,需要精确的焦点管理机制。RecyclerView作为动态列表的核心组件,其焦点控制涉及视图复用、导航逻辑和视觉反馈等核心技术点。通过合理配置focusable属性、自定义焦点查找算法以及优化动画性能,开发者可以解决TV端常见的焦点跳转异常、视觉反馈延迟等问题。特别是在视频点播、智能家居控制等场景中,良好的焦点控制能显著提升操作效率。本文结合网格布局焦点环绕、分页加载焦点保持等实战案例,深入解 阅读详情

学习一门语言有三个重要的部分必须要掌握:语法(该门语言的结构如何),词汇(如何用该语言命名你想要讨论的事物),用法(如何用惯用和高效的方式表达日常事物)。 那么《Effective Java》就是描述Java语言的用法很不错的一本书,阅读学习本书能够为程序员提供很多很好的编写Java代码的建议,从写代码的时候就避免掉进一些不必要的陷阱,减轻后续的debug的工作量。 也就是借鉴牛人们的经典建议,避免耗费大量时间在前人已经经历的弯路上。


本文以及之后的读书笔记内容均来自于《Effective Java》Second Edition Joshua Bloch 书中的建议。


首先简单温习下Java语言最基本的一些概念:

Java语言支持四种类型:接口(interface),类(class),数组(array)和基本类型(primitive)。前三种类型通常被称为引用类型(Reference type),类实例和数组是对象(object),而基本类型的值则不是对象。类的成员(member)由它的域(field)、方法(method)、成员类(member class)和成员接口(member interface)组成。方法的签名(signature)由它的名称和所有参数类型组成,签名不包括它的返回类型。


类,接口,构造器,成员以及序列化形式被统称为API元素(API element)。从一个包导出API由API实现所属包内所有可以被从包外访问的API元素组成,包含包中的每个共有(public)类或者接口中所有公有(public)的或者受保护(protected)的成员和构造器。


第2章 创建和销毁对象


1.考虑用静态工厂方法代替构造器(public static $CLASS_TYPE newInstance())【Item 1】

  静态工厂方法获取类的实例对象相较于直接通过类的构造器直接创建实例对象的优势有:

  1) 静态工厂方法的名字比构造器的参数更加清晰明了的描述了当前创建的是一个什么了作用的对象

  2) 不必每次调用静态工厂方法时都创建一个新对象,而构造器调用一次创建一个新对象

  3) 静态工厂方法增加创建对象类型的灵活性,可以返回原返回类型的任何子类型的对象,这种方式为未来代码实现调整提供了方便,并且隐藏了API的具体实现

  4) 静态工厂方法在创建参数化类型实例的时候,使得代码变得更加简洁,这里需要用到泛型

  而静态工厂方法的缺陷在于:

  1) 类如果不含有public或者protected的构造器,就不能被子类化,因为子类必须隐式或显式的调用父类的构造方法

  2) 静态工厂方法其实与其它静态方法没有任何区别,这降低了此类的易读性,因为不知道该静态方法的设计初衷的维护人员不能直观的明白其作用,建议增加注释说明

2.构造方法需要有较多的参数时建议考虑构建器(builder)【Item 2】

  1) 对于有类的构造需要较多参数时,可以通过构造方法的重叠来处理,第一层构造方法可以包含必要的几个参数,下一层构造方法可以在第一层的基本上增加几个可选参     数....知道最后一层构造方法包含所有必选参数以及可选参数。这种方式的缺点在于当类的构造需要很多参数时,构造方法的层层重叠使得客户端的代码较难写,并且代码可读性差

  2) JavaBeans方式,类仅提供无参数的构造方法,客户端通过setter方法来设置每个必要的参数以及每个可选参数,这种方式看起来解决了类构造方法的重叠的问题,但是这样使得类可变,可变就意味着多线程安全性需要我们付出额外的努力

  3) Builder模式,不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造方法或者静态工厂方法获得一个Builder对象,通过Builder的setter方法来设定可选参数,设定完成之后调用无参数的build方法获取类的实例对象。Builder的每个setter方法均返回Builder类型对象,这样保证setter方法可以连续调用(builder.setA().setB()),这样可读性和多线程安全性都能得到保证。但需要注意,builder的setter方法需要进行参数校验,如果发现设定了非法参数需要抛出相关异常。

3.用私有构造器或者枚举类型强化Singleton属性【Item 3】

  1) 将构造器访问权限设置为private,通过public static final修饰静态成员变量,该变量new出类的对象,保证该类实例的单一,这种方式需要在private构造器中通过check只被new了一个实例,如果有程序通过反射来直接调用private构造器时需要抛出异常提示错误

  2) 通过public静态工厂方法控制类实例的单一性,但本方式如果在实现序列化时需要声明所有实例的成员变量为transient的,并提供一个readResolve方法,否则每次在反序列化时都会重新创建一个实例。

  3) JDK 1.5之后只需编写一个包含单个元素的枚举类型即可保证singletone属性,同时在面对负责的序列化以及反射攻击都可以防止多实例化,其为实现Singletone最佳方式。

4.通过私有构造器强化不可实例化的能力【Item 4】

   本方式可以防止设计初衷本类不需要被实例化,如所有类成员均为static的类,不需要被实例化。但是本方式会导致类不能被子类化。

5.避免创建不必要的对象【Item 5】

  1) Java中的8大基本类型(byte,char,boolean,int,short,long,float,double)不是引用类型,而Java定义针对八大基本类型的引用类型,在需要的时候会将基本类型包装为其对应的引用类型,这叫自动包装机制。而在仅需基本类型计算的程序中,如果使用基本类型的包装类会导致基本类型的包装类多次被实例化,创建一些不必要的对象,这种场景是不合适的编码方式,在编码时需要注意

  2) 要优先使用基本类型儿不是包装基本类型,当心无意识的自动包装的发生。

  3) 对一些小对象的创建与销毁的代价比较小,不必刻意使用重用对象机制(对象池),而对于创建销毁代价高昂的数据库/线程等对象的创建需要谨慎,能够重用的对象尽量重用。

6.消除过期的对象引用(内存泄露三个常见来源:无意识过期引用被长久持有,缓存,监听器和其它回调。内存分析工具:Heap剖析工具(Heap Profiler))【Item 6】

  1) Java虽然不用程序编写者负责内存的管理,其使用的GC机制来自动进行内存的回收,但是GC的规则是会回收不再被引用的对象实例,如果对象在我们编写代码是无意识的长期持有,则不会被GC机制回收,从而导致引用对象不断增长,出现内存泄露

  2) 如果对象引用已经没有用了,一定记得将其置为null,以便GC回收。

  3) 如果你在最紧凑的作用域内定义每一个变量,那么引用对象的生命周期会自然而然的结束,从而其占用内存得到回收

  4) 只要是类自己管理内存,程序员就应该警惕内存泄露问题,一旦元素被释放掉,则该元素中所包含的任何对象引用都应该被清空

  5)内存泄露一个常见来源为缓存,一旦你把对象引用放到缓存中,则它很容易被遗忘掉,从而使得它不再有用之后很长一段时间内仍然留在缓存中,这种问题可以用WeakHashMap等已于被回收的类型来代替缓存,其随着生命周期的结束被回收

  6) 内存泄露另一个来源则是监听器和其它回调,如果你实现了一个API,客户端在API中注册回调,却没有显式的取消注册,则这些注册会被聚集。确保回调立即被当做垃圾被回收的最佳方法是只保存他们的弱引用(weak reference)

7.避免使用finalize方法【Item 7】

  1) Java语言不能保证finalize被及时的执行,甚至不能保证被执行,因此想依附该方法保证被回收是不可靠的。

  2) 如果未被捕获的异常在finalize过程中被抛出来,那么该异常会被忽略,并且该对象的终结过程也会终止,不会像正常方法中发生异常会使得线程执行被终止,病发出Stack Trace,finalze过程中异常不会打印且警告都不会打印,从而增加了出问题后的debug难度,而如果你真的需要使用finalize方法,那么建议在异常时主动打印warning类型的log作为提示

  3) 不建议依赖finalize方法的调用进行必须释放资源的释放和销毁,那么像对象中封装的例如文件或线程等资源确实需要释放或终止,只需提供一个显式的终止方法,并要求客户端程序主动调用即可,如果在被终止之后,还有方法调用被终止的资源时需要抛出IllegalStateException。

  4) 显示的终止方法通常与try-finally结构结合起来使用,以确保及时终止。

  5) 那么finalize方法的作用是什么呢?其应该作为最后一道安全网进行使用,即在程序员做了任何主动终止和释放相关资源的努力下仍然有遗漏的可能,则可以以来finalize方法的调用进行最后的释放。

  6) finalize方法的调用不会像构造器一样能够被自动执行调用链,即子类构造方法被调用会自动调用父类的构造方法。finalize方法需要主动调用,如果子类中的finalize方法调用需要同步调用父类的finalize方法需要显式调用super.finalize方法。

  7) 如果使用finalize方法作为最后一道完全网,防止finalize方法的非法调用最好能够在finalize方法中添加warning类型的log打印


STM32F103新手必看:0.96寸OLED屏幕从接线到动态显示全攻略(附IIC避坑指南) 本文为STM32F103新手提供了0.96寸OLED屏幕从硬件接线到软件驱动的完整实战指南。重点解析了IIC通信的时序、设备地址(0x78/0x7A)的常见陷阱,并详细演示了如何实现字符显示与平滑滚动显示等动态效果,帮助开发者快速上手并避开常见调试难题。 阅读详情

相关推荐

Unity 调用安卓内部安装apk

一、申请权限 应用内安装其他应用的权限属于特殊权限,需要在特殊申请。 Uri packageURI = Uri.parse("package:" + mContext.getPackageName()); Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI); startA...

BDDNH的博客 1238

Effective Java 读书笔记:(1) 用静态方法代替构造器

用静态方法替代构造器 对于一个类而言,为了让客户端获取到它的一个实例.在通常情况下,是提供这个类的构造器. 类可以提供一个公有的静态工厂方法(static factory method),这是一个返回类的实例的静态方法. 实例 : 下面是一个来自Boolean(基本类型boolean的装箱类)的简单实例,这个方法将boolean类型装换为一个Boolean的引用 //JDK1.8 pub...

WALL.E 355

利用Arcgis提取nc数据并计算区域年均温

1.下载数据。2.解压数据至不含中文的路径中。打开工具箱中的多维分析工具-创建NetCDF栅格图层,导入数据。3.打开工具箱中的数据管理工具-图层和表视图-创建栅格图层,导入数据,对输出数据进行命名,得到月均温栅格数据。4.选择工具箱-Spatial Analyst工具(空间分析工具)-地图代数-栅格计算器,计算全国一年年均温。​5.将其导出为.tif格式数据,方便后期使用。6.选择工具箱-Spatial Analyst工具(空间分析工具)-区域分析--以表格显示分区统计,得到分区域的气温数据。

什么都学亿点点的博客 7990

构造函数属性为protected或者private时

在c++中(不仅限于c++),一个函数被声明为protected或者private时,那也就意味着不能被外部直接调用了://类的成员函数add()是private class cla{ private: int add(int a, int b){ return a + b; }public: int my_func(){ add(5, 6);

echo_bright_的博客 2953

LabView实战:精准实现float到十六进制的转换与高低位拆分

本文详细讲解了在LabVIEW中实现单精度浮点数(float)到十六进制字符串转换,并进行高低16位拆分的实战方法。针对工业通信中设备协议要求,核心使用强制类型转换(Type Cast)获取内存原始数据,避免数值转换错误,并提供了完整的VI构建步骤、交叉验证技巧及常见踩坑经验(如字节序、字符串格式),确保数据通信的准确性。

assembly8low的博客 1765

昆仑通态屏幕制作(连载1)---接触篇

写在开始 背景:最近出了做QT、LORA和4G,还做了一个屏幕。以前做了一个迪文的串口屏幕,发现网上的教程很多,所以连载就不更新了,并且迪文屏幕的设置什么的比较简单,应该从网上都能找到对应的教程。而现在用的昆仑通态的屏幕属于嵌入式屏幕,至于为啥叫嵌入式,也不是很明白,反正就是需要用这个屏幕,嵌入式不嵌入式不重要了。重要的是能用,并且能实现串口屏幕不能实现的功能。所以选定昆仑通态的一款屏幕。 文章语言:我比较习惯用比较糙的语言介绍做的东西,有时候不太准备,但是为了方便理解,还请大家谅解。用...

weixin_45426095的博客 6735

第五条 避免创建不必要的对象。

1、重用对象。一般来说重用对象即快速又流行。String s = new String (“ss”)千万不用使用这种方式,String s = “ss”,只用了一个实例,而不是每次执行的时候创建了一个新的实例,并且可以使用到了字符串的常量池技术。对于提供了静态工厂方法和构造器的不可变类,优先使用静态工厂方法而不是构造器,避免创建不必要的对象。例如Boolean.valueOf(String)总是优...

liyang1518的博客 262

手把手教你用STM32CubeMX配置I3C通信(含动态地址分配实战)

本文提供了一份基于STM32CubeMX配置I3C通信的实战指南,重点讲解了动态地址分配的实现步骤。通过详细的工程配置、从设备枚举、CCC命令使用及数据读写示例,帮助开发者快速掌握这一高效通信协议,以替代传统的I2C或SPI接口,满足多传感器连接与低功耗设计需求。

c8d9e0f1的博客 542

Java 代码性能优化

代码优化,一个很重要的课题。可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用,但是,吃的小虾米一多之后,鲸鱼就被喂饱了。代码优化也是一样,如果项目着眼于尽快无BUG上线,那么此时可以抓大放小,代码的细节可以不精打细磨;但是如果有足够的时间开发、维护代码,这时候就必须考虑每个可以优...

weixin_30553065的博客 140

海康机器人ID5000 系列智能读码器(三)

又過了兩個月,漸漸的對這個攝像頭的功能更加熟悉了,而實際上,我要做的功能也越來越複雜,從一開始的讀碼,到後來的通過讀二維碼控制設備,再到未讀到二維碼控制設備等,下面就對具體的細項做一個總結。了解完這些就能對ID5000這個設備,乃至很多海康的設備都能做一個二次開發。

qq_54359036的博客 3071

DISM错误87详解:RestoreHealth选项无法识别的修复方法

DISM(部署映像服务和管理工具)是Windows系统维护与修复的核心命令行工具,常与SFC(系统文件检查器)配合使用,用于扫描和修复组件存储损坏、系统文件缺失等问题。在执行系统健康检查时,用户常会遭遇错误87,提示“未在此上下文中识别出restorehealth选项”。该错误的本质并非工具损坏,而是命令参数结构不符合DISM的语法解析规则,或当前系统环境(如Windows 7、WinRE/PE、32位环境)不支持该参数。理解DISM的命令层级、参数挂载关系以及运行上下文,是精准排除故障的前提。通过核对标准

weixin_34116482的博客 468

关于Java代码优化的N条建议!

本文是作者:五月的仓颉 结合自己的工作和平时学习的体验重新谈一下为什么要进行代码优化。在修改之前,作者的说法是这样的: 就像鲸鱼吃虾米一样,也许吃一个两个虾米对于鲸鱼来说作用不大,但是吃的虾米多了,鲸鱼自然饱了。 代码优化一样,也许一个两个的优化,对于提升代码的运行效率意义不大,但是只要处处都能注意代码优化,总体来说对于提升代码的运行效率就很有用了。 这个观点,在现在看来,是要进行代码优化的...

徐泗空的博客 335

PyCharm配置SSH远程解释器第3步时弹框报错:com.google.gson.stream.MalformedJsonException: Expected value at l...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1928

Effective Java 第2章: 创建和销毁对象

一、用静态工厂方法代替构造器 静态工厂方法与构造器相比有以下几个优点: 静态工厂方法有名称; 不必每次调用的时候都创建新的对象; 可以返回原返回类型的任何子类型的对象; 在创建参数化类型实例的时候没,静态工厂方法使得代码变得更加简洁; 缺点: 类如果不含有公有的或者受保护的构造器,就不能被子类化; 静态工厂方法与其他的静态方法实际上并没有任何区别; 静态工厂方法常用的名称: valueO...

NullPointerException的博客 359

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

《Effective Java 2nd》第2章 创建和销毁对象

第1条:考虑使用静态工厂方法代替构造器 通过使用静态工厂方法而不是使用构造器来创建类。 举例:Boolean.valueOf(boolean)方法,将boolean转换为Boolean对象引用。 有以下优势: 1)静态工厂方法有名称,可以表示方法的意思 2)不必在每次调用的时候都创建新对象(对象缓存能力)。 不可变类可预先构建实例,缓存起来重复使用。 3)可以返回原返回类型的任何子类型的对象 4)在创建参数化类型的时候代码更简洁。 //我们平时创建list List<String&

146

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

effective java 第2章-创建和销毁对象 读书笔记

背景 去年就把这本javaer必读书——effective java中文版第二版 读完了,第一遍感觉比较肤浅,今年打算开始第二遍,顺便做一下笔记,后续会持续更新。 1、考虑用静态工厂方法替代构造器 优点 静态工厂方法与构造器不同的第一大优势在于,他们有名称,比多个通过不同参数的构造器更具有辨识度。 静态工厂方法与构造器不同的第二大优势在于,不必在每次调用他们的时候都创建一个新对象。 静...

dianziyuan8553的博客 236

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

[Java读书笔记] Effective Java(Third Edition) 第2章 创建和销毁对象

第 1 条:用静态工厂方法代替构造器 对于类而言,获取一个实例的方法,传统是提供一个共有的构造器。 类可以提供一个公有静态工厂方法(static factory method), 它只是一个返回类的实例的静态方法。 示例:Boolean的装箱类,将boolean基本类型值转换成一个Boolean对象引用 public static Boolean valueOf...

weixin_30702887的博客 210

walter的《Effective JAVA》 读书笔记-第2章 创建和销毁对象

  创建和销毁对象 转载请注明出处:http://lt200819.iteye.com/blog/1707699 第1条:考虑用静态工厂方法代替构造器(静态工程方法不同于设计模式中的工厂方法) 静态工厂方法与构造器不同的优势在于: 1.它们有名称; 2.不必每次调用它们的时候都创建一个新的对象,类似单例模式。 3.可否返回原返回类型的任何子类型的对象。(服务提供者框架) 4.在创建...

lt200819的专栏 162

读书笔记:Effective Java-第2章 创建和销毁对象

Effective Java-第2章 创建和销毁对象

XinYuDaHai的博客 227

Effective Java 第2章 创建和销毁对象 精简总结 (1)

第2章 创建和销毁对象第一条 用静态工厂方法替代构造器实例代码 /** * 静态工厂方法 */ public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; } public static void main(String[] ar

首席科学家 599

Effective Java读书笔记(1-2章-创建和销毁对象)

Java经典的书籍有几本,都是很多有经验的开发人员推荐的,包括Java编程思想,深入理解Java虚拟机,Java核心技术和Effective Java。工作之后发现自己读的技术书籍少的可怜,因为不爱读书,连面试都通不过。从最近开始,打算好好的看书,把这些经典的书籍好好的看一遍,把重要的内容记下来。以下是Effective Java的读书笔记:        第一章  引言       

lyl_tkb的专栏 757

《Effective java 第二版 中文版》第2章 创建和销毁对象

Normal 0 7.8 磅 0 2 false false false ...

cuad2192的博客 205

Effective Java读书笔记(第2章-创建和销毁对象续)

第5条: 避免创建不必要的对象

lyl_tkb的专栏 395

Effective Java 读书笔记(第2章 创建和销毁对象)——持续更新中

第一条: 考虑用 “静态工厂方法” 代替 “构造器” 此处的 “静态工厂方法” 不直接对应设计模式中的工厂方法。 “静态工厂方法” 相对于 “构造器”有以下4点优势: 第一大优势:有名称。 名字可用于描述被返回的对象,易于阅读和字面理解。类似 bigApple()、smallApple()可以很形象表述要返回对象的特征。   第二大优势:不必每次调用都创建一个新对象。 比如 “单例模...

ding3106的专栏 262

笔记《Effective Java》01: 创建和销毁对象

《Effective Java》这本书可以说是程序员必读的书籍之一。这本书讲述了一些优雅的,高效的编程技巧。对一些方法或API的调用有独到的见解,还是值得一看的。刚好最近重拾这本书,看的是第三版,顺手整理了一下笔记,用于自己归纳总结使用。建议多读一下原文。今天整理第一章节:创建和销毁对象。

有一只柴犬的专栏 1852

【总结】Effective java经验之谈,创建和销毁对象

关于Effective java 这本书,自己的一些总结性的思考。篇幅可能不按照目录来,因为自己喜欢先看哪一章就直接阅读了。不过能确定的是,每一章都会有总结。欢迎大家拍砖与补充。

阿利在努力 2302
上一篇: 设计模式-可复用面向对象软件的基础 [读书笔记]
下一篇: 《Effective Java》第3章 对于所有对象都通用的方法
AnnaLoad
博客等级 码龄17年 7粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值