Effective Java笔记(6)避免创建不必要的对象

强化学习-动态规划 动态规划(dynamic programming)是程序设计算法中非常重要的内容,能够高效解决一些经典问题,例如背包问题和最短路径规划。动态规划的基本思想是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到目标问题的解。动态规划会保存已解决的子问题的答案,在求解目标问题的过程中,需要这些子问题答案时就可以直接利用,避免重复计算。本章介绍如何用动态规划的思想来求解在马尔可夫决策过程中的最优策略。 阅读详情

        一般来说,最好能重用单个对象,而不是在每次需要 的时候就创建一个相同功能的新对象 。 重用方式既快速,又流行 。 如果对象是不可变的( immutable ) (详见第 17 条),它就始终可以被重用 。

        作为一个极端的反面例子,看看下面的语句 :

String s = new String("bikini"); // DON'T DO THIS!

        该语句每次被执行的时候都创建一个新的 String 实例,但是这些创建对象的动作全都是不必要的。 传递给 String构造器的参数(bikini)本身就是一个 String 实例,功能方面等同于构造器创建的所有对象 。 如果这种用法是在一个循环中,或者是在一个被频繁调用的方法中,就会创建出成千上万不必要的 String 实例 。

        改进后的版本如下所示 :

String s = "bikini";

        这个版本只用了 一个 String 实例,而不是每次执行的 时候都创建一个新的实例 。 而且,它可以保证,对于所有在同一台虚拟机中运行的代码,只要它们包含相同的字符串字面常量,该对象就会被重用。

        对于同时提供了静态 工厂方法( static factory method) 和构造器的不可变类,通常优先使用静态工厂方法而不是构造器,以避免创建不必要的对象 。 例如,静态工厂方法Boolean.valueOf(String )几乎总是优先于构造器 Boolean(String),注意构造器 Boolean(String)在 Java 9 中已经被废弃了 。 构造器在每次被调用的时候都会创建一个新的对象,而静态工厂方法则从来不要求这样做,实际上也不会这样做 。 除了重用不可变的对象之外,也可以重用那些已知不会被修改的可变对象。

        有些对象创建的成本比其他对象要高得多 。 如果重复地需要这类“昂贵的对象”,建议将它缓存下来重用 。 遗憾的是,在创建这种对象的时候,并非总是那么显而易见 。 假设想要编写一个方法,用它确定一个字符串是否为一个有效的罗马数字 。 下面介绍一种最容易的方法,使用一个正则表达式 :

        这个实现的问题在于它依赖 String.matches 方法 。虽然String.matches 方法最易于查看一个字符串是否与正则表达式相匹配 , 但并不适合在注重性能的情形中重复使用 。 问题在于,它在内部为正则表达式创建了一个 Pattern 实例,却只用了一次,之后就可以进行垃圾回收了 。 创建Pattern实例的成本很高 ,因为需要将正则表达式编译成一个有限状态机( finite state machine)。

        为了提升性能,应该显式地将正则表达式编译成一个 Pattern实例(不可变),让它成为类初始化的一部分,并将它缓存起来,每当调用 isRomanNumeral 方法的时候就重用同一个实例:

         改进后的 isRomanNumeral 方法如果被频繁地调用,会显示出明显的性能优势。

        如果一个对象是不变的,那么它显然能够被安全地重用,但其他有些情形则并不总是这么明显 。 考虑适配器( adapter )的情形,有时也叫作视图( view ) 。 适配器是指这样一个对象 :它把功能委托给一个后备对象( backing object ),从而为后备对象提供一个可以替代的接口 。 由于适配器除了后备对象之外, 没有其他的状态信息,所以针对某个给定对象的特定适配器而言,它不需要创建多个适配器实例 。

        例如 ,Map 接口 的 keySet 方法返回该 Map 对象的 Set 视图,其 中包含该 Map 中所有的键(key) 。 乍看之下 ,好像每次调用 keySet 都应该创建一个新 的 Set 实例,但是,对于一个给定的 Map 对象,实际上每次调用 keySet 都返回同样的 Set 实例 。 虽然被返回的 Set 实例一般是可改变的,但是所有返回的对象在功能上是等同的 :当其中一个返回对象发生变化的时候,所有其他的返回对象也要发生变化,因为它们是由 同一个 Map 实例支撑的 。 虽然创建 key Set 视图对象的多个实例并无害处, 却是没有必要,也没有好处的 。

        另一种创建多余对象的方法,称作自动装箱( autoboxing ),它允许程序员将基本类型和装箱基本类型( Boxed Primitive Type )混用,按需要自动装箱和拆箱 。自动装箱使得基本类型和装箱基本类型之间的差别变得模糊起来, 但是并没有完全消除 。 它们在语义上还有着微妙的差别,在性能上也有着比较明显的差别 。 请看下面的程序,它计算所有int正整数值的总和 。 为此,程序必须使用 long 算法,因为 int 不够大,无法容纳所有 int 正整数值的总和:

private static long sum() {
    Long sum = OL;
    for (long i = 0; i <= Integer.MAX_VALUE; i++)
        sum += i;
    return sum;
}

        这段程序算出的答案是正确的,但是比实际情况要更慢一些,只因为打错了一个字符 。 变量 sum 被声明成 Long 而不是 long ,意味着程序构造了大约 231 个多余的 Long 实例(大约每次往 Long sum 中增加 long时构造一个实例) 。 将 sum 的声明从 Long 改成long ,在我的机器上使运行时间从 6.3 秒减少到了 0 . 59 秒 。 结论很明显 :要优先使用 基本类型而不是装箱基本类型,要当心无意识的自动装箱 。

        不要错误地认为本条目所介绍的内容暗示着“创建对象的代价非常昂贵,我们应该要尽可能地避免创建对象” 。 相反,由于小对象的构造器只做很少量的显式工作,所以小对象的创建和回收动作是非常廉价的,特别是在现代的 JVM 实现上更是如此 。 通过创建附加的对象,提升程序的清晰性、简洁性和功能性,这通常是件好事 。

        反之,通过维护自己的对象池( object pool )来避免创建对象并不是一种好的做法,除非池中的对象是非常重量级的 。 正确使用对象池的典型对象示例就是数据库连接池 。 建立数据库连接的代价是非常昂贵的,因此重用这些对象非常有意义 。 而且,数据库的许可可能限制你只能使用一定数量的连接 。 但是,一般而言,维护自己的对象池必定会把代码弄得很乱,同时增加内存占用( footprint ),并且还会损害性能 。 现代的 JVM 实现具有高度优化的垃圾回收器,其性能很容易就会超过轻量级对象池的性能 。

PoP(Package on Package)封装技术探讨 PoP(Package on Package)封装技术摘要 PoP是一种3D封装技术,通过垂直堆叠已完成封装的器件(如SoC+DRAM)实现高密度集成,典型应用于智能手机等空间受限场景。其核心优势包括:节省主板面积(垂直堆叠)、优化高速信号完整性(短互连路径)、提升供应链灵活性(独立测试与选型)。PoP结构分为底封装(通常为Flip-Chip BGA的SoC)和顶封装(如FBGA存储芯片),通过焊球阵列互连,一次回流焊完成组装。 阅读详情

相关推荐

Openwork 入门指南:开源 AI 桌面助手快速上手

Openwork是一款开源的AI桌面代理工具,提供类似Claude Cowork的免费替代方案。它支持本地运行,确保隐私安全,并能高效处理文件整理、文档读写等任务。支持多种AI模型,通过MIT许可完全免费。安装简单,仅需运行命令行或下载桌面版,需配置API Key后即可使用。操作直观,支持多步骤规划和权限控制,适合自动化重复工作。目前主要支持macOS,未来将扩展至Windows/Linux。建议从简单任务入手,逐步掌握这一高效的数字助手工具。

3802

《Effective Java》学习笔记 - (6) 避免创建不必要的对象

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言避免创建不必要的对象1. 引入2. 解决的一些建议1. 关于常量String的创建2. 对于静态工厂方法和构造器 前言 最近在看《Effective Java》这本书,也顺便记录下书里的一些内容,有些看不懂的暂时先放着。 避免创建不必要的对象 1. 引入 一般来说,程序里面最好能用单个对象,而不是需要一个就创建一个,其实这种方式也很常见: springboot的@Autowired注解 单例模式 池化技术(这里归为这一类其

Jwasx的博客 243

从数据校准到论文呈现:fsQCA与NCA方法融合的完整实证研究指南

本文详细介绍了fsQCA(模糊集定性比较分析)与NCA(必要条件分析)方法融合的完整实证研究流程,从数据校准到论文呈现。通过软件操作技巧、R语言NCA包高效使用及论文写作规范,帮助研究者避免常见误区,提升研究质量与可靠性。特别适合需要进行组态分析的研究生和学者参考。

weixin_29215391的博客 414

Effective Java3 Item6:避免创建不必要的对象(内容及笔记)

重用单个对象通常是合适的,不必每次需要时都创建一个新的功能等效对象。重用可以更快、更时尚。如果对象是不可变的,那么它总是可以被重用的(Item 17)。 作为一个不该做的极端例子,请考虑下面的语句: String s = new String("bikini"); // DON'T DO THIS! 该语句每次执行时都会创建一个新的 String 实例,而这些对象创建都不是必需的。String ...

bulibuqiqin的博客 255

别再只会用Excel了!Minitab 21手把手教你搞定SPC控制图(从数据导入到结果解读)

本文详细介绍了如何使用Minitab 21高效制作SPC控制图,从数据导入到结果解读的全流程。通过对比Excel的局限性,展示Minitab在自动化计算、图表标准化和特殊原因检验等方面的优势,帮助质量管理人员提升工作效率和数据分析专业性。

weixin_30878501的博客 383

论文理解【LLM-OR】—— 【PaMOP】Guiding Large Language Models in Modeling Optimization Problem

针对 LLM 求解运筹优化任务,PaMOP 通过约束划分树分离子问题,实现复杂优化问题的分块建模,并结合求解器反馈与反向翻译一致性检查迭代纠错,降低子任务复杂度,提升可执行率与建模准确性。

佚失的诗篇 1007

【Effective Java】第6条:避免创建不必要的对象

在Java编程中,对象创建是一个常见的操作,但并非所有对象创建都是必要的。虽然“避免创建不必要的对象”是一个重要的原则,但在某些情况下,使用对象池来重用对象也是合理的。例如,在数据库连接管理中,创建和销毁连接的成本很高,因此使用连接池来重用连接是一个很好的选择。“避免创建不必要的对象”是Java编程中的一个重要原则,它有助于减少内存消耗、提高程序性能和增强代码的可读性。当使用字符串字面量时,JVM会检查常量池中是否已存在相同的字符串,如果存在则直接返回该字符串的引用,而不是创建一个新的字符串对象。

2401_86224057的博客 900

secureCRT 破解方法

3、输入注册信息打开keygen.exe,点击path,选择SecureCRT的安装目录(例如D:\VanDykeSoftware\Clients)的securecrt.exe打开,继续下一步打开LicenseHelper.exe,如下。1、注册SecureCRT9.1打开keygen.exe,出现以下问题(没有关掉安全防护,一双击打开,Windows会自动识别keygen.exe为bingdu并删除)打开桌面SecureCRT,此界面不输入内容,直接点击下一步。2、存储配置文件夹(可以默认安装)

逆水行舟 1万+

Java:Effective java学习笔记之 避免创建不必要的对象

Java避免创建不必要的对象避免创建不必要的对象1、采用更合适的API或工具类减少对象的创建2、重用相同功能的对象3 、小心自动装箱(auto boxing)参考 避免创建不必要的对象 在Java开发中,程序员要尽可能的避免创建相同的功能的对象,因为这样既消耗内存,又影响程序运行速度。在这种情况下可以考虑重复利用对象。 尽量少的创建对象,如果单个对象能够满足要求,就使用单例模式,反复重用唯一的对象。对一些创建成本低的对象来说,这样做带来的好处也许并不明显。但对于一些创建成本高的对象来说,这样做可以明显地节约

JMW1407的博客 1160

课程1:认识Asp.net Core Web API

本文是《.Net Core从零学习搭建权限管理系统》教程专栏的导航站(点击链接,跳转到专栏主页,欢迎订阅,持续更新…)专栏介绍:以实战为线索,基于.Net 7 + REST + Vue、前后端分离,不依赖任何第三方框架,从零一步一步讲解权限管理系统搭建。专栏适用于人群:Web后端开发人员Web API是一个很广泛的概念,Asp.net Core Web API是.NET框架用于创建RESTful风格的项目、用于轻松构建可供多个客户端访问的HTTP服务。1、支持RestFul风格编程;

成长的足迹 1256

Unity必学:Protobuf-net预编译实战

本文深入解析Unity项目使用Protobuf-net Precompile的必要性。作为高效跨平台序列化方案,Protobuf-net解决了Unity工程在网络同步、存档系统中的性能瓶颈,特别是针对iOS等AOT平台的兼容问题。通过预编译模式,将运行时反射转为静态代码生成,显著提升移动端性能表现,支持协议平滑升级,已成为大厂项目的标配方案。文章从原理、实践到多平台适配,全面展示了这一"序列化发动机"如何支撑现代Unity项目的数据传输需求。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 495

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

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

有一只柴犬的专栏 1852

MIKE 21 教程 2.2 Domain, Time, Module Selection设置教学

上一节讲解了水动力模型的基本概念与文件创建MIKE 21 教程 2.1水动力模型介绍​本节讲解水动力模型前三个模块的设置此模块需导入之前绘制好的网格文件,导入后可预览网格文件点击上方的Domain Specification可查看网格的数据统计与高程属性,快速检查网格文件有无明显错误 点击上方的Boundary names,可查看之前定义的出入水边界。在网格文件中,我们对边界只能以数字属性进行区分,这里可以对数字属性进行命名,在name中直接修改即可。本实例中我们的2代表入水边界,3代表出水边界。因为博主日

Hello Word 3866

《Effective java》读书笔记1——避免创建不必要的对象

Java中Sting很特别,有如下两种初始化方式: (1).String s1 = “This isstring1”; (2).String s2 = new String(“Thisis string2”); 第一种字符串初始化方式,当有多于一个字符串的内容相同情况,字符串内容会放在字符串缓冲池中,即字符串内容在内存中只有一份。 第二种字符串初始化方式,不论有没有字符串值相同,每次都会在

Tony Chen的专栏 2962

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

《Effective Java》第6条:避免创建不必要的对象

虽然被返回的 Set 实例一般是可改变的,但是所有返回的对象在功能上是等同的:当其中一个返回对象发生变化的时候,所有其他的返回对象也要发生变化,因为它们是由同一个Map实例支撑的。而这些对象功能方面完全一样,所以创建这些对象的动作全都是不必要的。相反,由于小对象的构造器只做很少量的显式工作,所以小对象的创建和回收动作是非常廉价的,特别是在现代的JVM实现上更是如此。1、本条目不是要你遇见对象就考虑避免创建多重对象,而是要视情况而定,对于小对象而言,它的创建和回收是非常廉价的,现代JVM已经优化的很好了。

TD_FAlmK的博客 659

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Effective Java 避免创建不必要的对象

《Effective Java》第二章创建和销毁对象第5条提到,在开发过程中,需要避免创建不必要的对象,最好能重用对象而非在每次需要的时候就创建一个相同功能的新对象。如果对象是不可变的,它就始终可以被重用,而不用创建新的实例,从而降低内存占用和垃圾回收的成本。例如,创建字符串 // Don't do this! String s = new String("stringette"); // 优化版 String s = "stringette"; 第二行代码每次被执行的时候都创建一个...

菜园子丶For丨丶Tomorrow的博客 186

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Effective Java -- 避免创建不必要的对象

此系列文章为本人对《Effective Java》一书的学习笔记,主要是记录对书中重点内容的理解。既然有缘看到此文,那么希望能对你有所帮助。本文对应原书 第6条 避免创建不必要的对象

心之所往 码之所向 271

Effective Java – Item 6 避免创建不必要的对象

item6 · 避免创建不必要的对象 例子 String s = new String("abcd"); // DON'T DO THIS! 上述语句每次被执行的时候都创建一个新的 String 示例,但是这些创建对象的动作全都是不必要的。传递给 String 构造器的参数 ("abcd") 本身就是一个 String 实例。 改进后的版本如下所示: String s = "abcd"...

AlbumenJ的博客 227

《Effective Java》阅读笔记5 避免创建不必要的对象

1.序 尽量少的创建对象,如果单个对象能够满足要求,就使用单例模式,反复重用唯一的对象。对一些创建成本低的对象来说,这样做带来的好处也许并不明显。但对于一些创建成本高的对象来说,这样做可以明显地节约系统资源、提升系统性能。有以下几种方法: 1 采用更合适的API或工具类减少对象的创建 2 重用相同功能的对象 3 小心自动装箱(auto boxing) 4 用静态工厂方法而不是构造器 2. 采用更合适的API或工具类减少对象的创建 可能导致滥用对象的一个典型例子就是 字符串 。在学习Java基础的过程中,

weixin_41563161的博客 366

Effective Jave 创建和销毁对象 5.避免创建不必要的对象

一般来说,对于能够重用的对象,而不是在每次需要的时候就创建一个相同功能的新对象。重用的方式即快速,又流行。如果对象是不可变,他就始终可以被重用。 String s=new String("person"); 该语句每次被执行时都会创建一个String实例,对于这些创建的动作完全是不必要的。传递给String构造器的参数,本身就是String实例,功能方面等同于构造器创建的所有对象。

yancyang的博客 2万+

Java 代码优化 -避免创建不必要的对象

《effective Java 》书中第六条写道避免创建不必要的对象,再次做一个总结 总结如下几点: 1.避免创建不必要的对象,比如字符串的创建不使用new方式 2.通过静态工厂方法可以创建不必要的对象 3.对象的复用 如果一些对象可以被复用 看下面 的一个例子 有下面一个正则校验数据的格式 static boolean isRomanNumeral(String s) { ...

tom有cat 790

深入理解《Effective Java》 之 条目6:避免创建不必要的对象

1.普通的对象创建消耗不大,完全可以放心创建,只有当创建对象的开销极为昂贵时,才推荐维护对象池的方式来避免创建对象,因为维护一个对象池也是会影响性能的。2.本条与保护性复制不冲突,前者重在性能优化,后者重在安全保护。

墨问的专栏 327

《Effective Java》避免创建不必要的对象

经典问题:这两行创建了几个对象?第一行创建了几个,第二行创建了几个? 第一行创建了一个对象,第二行也是创建了一个对象。引用一共有两个,一个在虚拟机栈的栈帧的局部变量表中,另一个是在全局字符串池中(StringTable,本质上是个哈希表,池的位置视JDK的版本而定,1.6版本在方法区,1.7版本在堆,1.8从堆里面独立,被称为元空间),这个池中只保留被双引号修饰的字符串引用,实际对象还是存储在堆...

Joseph_Geeker的博客 431

Effective Java 【创建和销毁对象篇】第6条 避免创建不必要的对象

避免创建不必要的对象 一般来说,如果对象是不可变的,最好重用一个对象,而不是每次需要的时候,就去重新一个相同功能的对象,重用可以提高性能。 作为一个反面例子,看看下面的语句: String s = new String("java");//类似于包装类,基础数据装箱 每次执行以上代码的时候,都会重新创建一个新的String实例,但是创建的实例功能和意义完全是不必要的,String构造器的参数(“java”)本身就是一个String实例,功能方面等同于构造器所创建的对象,如果以上代码是在一个循环体内,或者在

zhangxiaoxiao9527的博客 235

《Effective Java》5、避免创建不必要的对象

一般来说,最好能重用对象而不是每次需要的时候创建一个相同功能的新对象。 一些无意识创建不必要的对象的情况: String实例 String s=new String("gyx"); 上述语句每次被执行时都创建一个新的String实例,改进后为String s="gyx"; 自动装箱机制 Long sum = 0L; long start = System.currentTimeMillis(); for (int i = 0; i< Integer.MAX_VALUE; i++) { sum

Yisnow.的博客 180

Effective Java -- 创建和销毁对象 -- 避免创建不必要的对象

第二章 创建和销毁对象 第六条 避免创建不必要的对象 一般应该避免创建不必要的对象,可以通过优先使用静态工厂方法、将经常创建的对象缓存、优先使用基本类型而不是装箱基本类型等方式来避免。 但是要注意并非任何时候都要避免创建对象。

weixin_43164759的博客 195
上一篇: Effective Java笔记(5)优先考虑依赖注入来引用资源
下一篇: Effective Java笔记(7)消除过期的对象引用
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值