(设计原则)禁止编写返回可变对象引用的访问器方法

C++函数返回机制:传值、传引用与性能优化实战指南 在C++编程中,函数返回机制是影响程序性能和正确性的核心概念。从底层原理看,传值返回涉及对象拷贝构造,可能带来性能开销,但现代编译器通过返回值优化(RVO/NRVO)和移动语义能大幅消除不必要的拷贝。传引用返回通过传递地址实现零拷贝,但必须严格管理对象生命周期,避免悬空引用。理解这些机制对于编写高效、安全的代码至关重要,尤其在处理大型数据结构、实现链式调用或设计容器类接口时。本文深入解析了传值与传引用的底层实现、编译器优化策略及常见陷阱,并通过实战场景展示了如何根据对象生命周期、性能需求和代码安全性做出合理 阅读详情

现在有一个Employee类

class Employee {
    private Date hireDate;

    public Employee(Date date){
        this.hireDate = date;
    }

    public Date getHireDate() {
        return hireDate;
    }

}

对属性封装后对外提供一个访问器方法,看起来没毛病对吧。
接下来我们获取一个初始化一个员工对象,并进行一番操作

 	Employee employee = new Employee(new Date());
	System.out.println("新建时的员工发薪时间--->" 
	+ employee.getHireDate());
	Date d = employee.getHireDate();
	//设置时间为当前时间往前十年
    d.setTime(d.getTime() - (long)10*365*24*60*60*1000);
	System.out.println("修改引用d的发薪时间--->"+ d);
  	System.out.println("再次获取员工的发薪时--->:" 
  	+ employee.getHireDate());

结果如下:

新建时的员工发薪时间—>Tue Apr 19 16:18:22 CST 2022
修改引用d的发薪时间—>Sat Apr 21 16:18:22 CST 2012
再次获取员工的发薪时—>:Sat Apr 21 16:18:22 CST 2012

我们发现我们并没有提供修改器方法,但是仅仅通过访问器方法,将获取到的对象进行一番修改,仍然可以修改employee员工的发薪时间,这是有问题的。

这是因为d和employee.hireDay引用的是同一个对象。(实际指向的是内存中的同一个对象)
虽然我们没法直接对hireDay进行修改,但是对d调用的更改器方法就可以自动的更改这个Employee对象的私有状态。

	//这是Date类的setTime方法
    public void setTime(long time) {
        fastTime = time;
        cdate = null;
    }

如果以后碰到这种需要返回可变对象引用的访问器方法时,可以返回该属性的克隆。

 public Date getHireDate() {
        return (Date) hireDate.clone();
    }

这样的话d其实指向的是另外一个对象了,无论怎么修改也不会影响到原始对象的属性了。

【C++】5-1.5 不可变对象和类 【C++】5-1.5 不可变对象和类不可变对象不可变类三级目录 不可变对象 不可变对象:对象创建后,其内容不可改变,除非通过成员拷贝 不可变类 不可变类:不可变对象所属的类 三级目录 阅读详情

相关推荐

行政数据分析大屏实战:用Tableau从Excel到看板的完整搭建流程(含数据连接与字段计算避坑)

本文详细介绍了如何利用Tableau从Excel数据源搭建行政数据分析大屏的完整流程,涵盖数据准备、连接技巧、计算字段优化、看板设计及动态交互部署。通过五阶工作流,帮助用户高效处理多源异构数据,实现业务洞察与可视化呈现,提升行政数据分析效率。

weixin_29696711的博客 336

Java-不要编写返回可变对象引用的访问器方法

可以使用这个方法来设置毫秒数,这样就破坏了封装性。使得当我们没有提供set方法的情况下,也可以修改Date字段的数据。但是这样会产生一个问题,就是这个访问器方法返回的是一个对象,也就会导致当实例化的employee使用getDate方法后,获取到Date字段的引用。因此,我们在设计bean的时候,最好将这种返回可变对象引用的get方法(访问器方法)的内容,修改为返回克隆的对象。在我们创建一个JavaBean的时候,会使用到对象类型的私有字段,并为其提供访问器方法,如getDate();

qq_45726342的博客 167

Python自动化:3分钟搞定微信收藏链接批量导出到TXT(附完整代码)

本文介绍如何使用Python自动化工具在3分钟内将微信收藏链接批量导出到TXT文件。通过模拟人类操作和OCR技术,脚本高效处理大量链接,显著提升工作效率,并附有完整代码和实战避坑指南。

weixin_29062671的博客 627

Java不可编写返回引用可变对象的访问器方法

问题: 使用java进行编程时,有时会发现在一个类中明明定义的是private类型,结果却能够在其他类中被修改。 代码: class Employee { private String name; private double salary; private Date hireDay; public Date getHireDay(){ return hireDay; }

m0_37620545的博客 1591

TSMC65nm工艺下Virtuoso仿真gm-id曲线的保姆级教程(含ADE设置详解)

本文提供了一份在TSMC 65nm工艺下使用Cadence Virtuoso绘制gm-id曲线的详细教程。内容涵盖从理解gm/id方法学、搭建仿真环境、深度解析ADE设置,到运行DC仿真、提取数据并生成对数坐标曲线的完整流程。教程重点解析了Virtuoso ADE中的关键设置与常见避坑点,旨在帮助模拟集成电路设计初学者快速掌握这一核心设计工具,为高性能电路设计奠定基础。

grpc6streamer的博客 1171

[Dify实战] 招投标标书智能生成:模板套用 + 风险校验

摘要:本文提出基于Dify构建AI标书生成工作流,解决传统标书撰写中内容重复(80%复用率)、人工修改效率低、风险检查易出错等痛点。方案包含三大核心模块:1)智能生成(基于模板自动填充项目信息);2)风险校验(AI自动检查废标风险点);3)多角色协作。通过拆分标书结构、设置详细Prompt、建立风险检查清单,实现从"人工撰写"到"参数化自动生成+AI审核"的转型,最终输出标准格式文档并支持企业系统集成。典型应用场景下,系统能自动生成技术方案并识别关键风险(如支付安全合

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 827

java 访问器_java基础入门-数据访问器(set方法)与返回可变对象

今天写一个大家平常都比较忽略的一个问题set方法与返回可变对象我们平常在编程的时候,大部分的时候都是使用get、set方法来访问或者设置属性域但是在set的方法当中会出现一些比较特殊的例子,就像下面的代码,birthday手型,在set方法里面返回的是一个可变对象date,然后我们再通过这个date去改变属性域里面的值这种错误时经常出现在代码里面,正确的做法是在birthday的set方法里面加入...

weixin_34237362的博客 463

4、基于STM32 NUCLEO - F030R8开发板的嵌入式编程入门

本文详细介绍了如何在STM32 NUCLEO-F030R8开发板上实现LED闪烁功能,作为嵌入式编程的入门实践。内容涵盖开发板组成、跳线设置、项目创建、代码编写与解析、编译运行步骤,以及常见问题解决方法和拓展应用。通过本文学,习者可以掌握嵌入式开发的基本流程,并为后续深入学习打下基础。

m9n0o的博客 83

Java并发编程(六)不可改变对象

6. 不可改变对象如果一个对象在创建后不可改变,那么就称之为不可改变对象。基于不可变对象被广泛接受为创建简单、可靠代码的有效策略。不可变对象在并发程序中显得尤为重要。由于它们不能改变,所以他们不会在线程干扰中出现错误,并且不会出现非一致性状态。开发者并不太原因使用不可变对象,他们担心创建对象的开销比更新一个现有对象的开销大。创建对象的开销经常被夸大,并且可以被不可变对象带来的效率弥补。这包括由于垃圾

u014088294的专栏 3039

基于若依的ruoyi-nbcio-plus支持VForm3表单字段数据保存到数据库的一种方法——全网首创(一)

基于若依的ruoyi-nbcio-plus支持VForm3表单字段数据保存到数据库的一种方法——全网首创(一)

宁波阿成的博客 658

正确解决Authentication plugin ‘caching _sha2_password’ cannot be loaded:异常的有效解决方法

正确解决Authentication plugin ‘caching _sha2_password’ cannot be loaded:异常的有效解决方法

wbajsjhhhhh的博客 1万+

请不要编写返回可变对象的访问器(get)

为返回可变对象的访问器创建副本(克隆)

my blog 1369

华为OD机试真题 新系统【优化充电桩调度算法】

华为OD机试 新系统真题【优化充电桩调度算法】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【优化充电桩调度算法】

qq_45776114的博客 752

HoRain云--Java不可变对象设计终极指南

《Java不可变对象设计指南》摘要(149字) 本文详细讲解了Java中创建不可变对象的设计原则与实现方法。核心要点包括:将类声明为final、所有字段设为private final,构造器需对可变引用类型进行深拷贝,访问器方法返回防御性副本。文章提供了处理特殊场景的建议,如反射攻击防护和性能优化,并附有完整代码示例。通过遵循这些规范,开发者可以构建线程安全、高效稳定的不可变对象,适用于配置类、DTO等多线程场景。文末还贴心地提供了设计速查表,方便开发者快速查阅关键实现要点。

sinat_57153473的博客 878

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Laravel学习记录--访问器与修改器

简介 当你在Eloquent模型实例中获取或设置某些属性值的时候,访问器和修改器允许你对Eloquent属性值进行格式化,访问器可在将要读取的数据进行处理后在返回给调用方,而修改器可在数据要被保存到数据库时进行一些相关处理,如清除表单提交的空格,时间格式化等 访问器 要定义一个访问器,则需在你的模型上创建一个getFooAttribute方法。Foo为要访问的属性,命名规则采用驼峰法,但访问这个属...

Sumshine12.5 1843

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

OSG内存、访问器、回调和数据变量——(书籍后补)

OSG72讲学习

qq_42491346的博客 1080

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

JavaScript数组访问器方法原理与工程实践指南

JavaScript数组访问器方法是一组不修改原数组、返回新数据的只读操作函数,其底层基于不可变性原则与引擎级优化(如V8的预分配和SIMD向量化)。它们通过统一的语义协议(如SameValueZero比较、toString隐式调用、浅拷贝机制)实现安全的数据探查与转换,在函数式编程、状态管理、前端监控等场景中承担关键角色。掌握concat、join、slice、includes等核心方法的行为边界与性能特征,能有效规避null/undefined隐式转换、引用穿透、稀疏数组误判等高频工程陷阱,并为toRe

weixin_30617737的博客 396

Java 不可变对象完全指南:从原理到实践

原创内容,请勿转载。不可变对象是构建健壮、可维护 Java 应用的重要基石。本文将系统介绍不可变对象的核心概念、实现方式及最佳实践,帮助开发者掌握这一关键编程范式。核心收获Record 类型为简单数据对象提供最简洁的实现手动实现需要注意防御性拷贝和深不可变保证Lombok 和 Immutables 库大幅减少模板代码Guava 不可变集合提供生产级的安全保障设计原则优先选择深不可变设计对集合类型使用专业不可变实现在构造函数和访问器中贯彻防御性编程根据场景平衡性能与安全性需求。

2501_93078354的博客 801

【C# 9记录类型深度解析】:如何利用Record实现真正不可变对象设计

掌握C# 9记录类型(Record)不可变性设计精髓,轻松构建线程安全、易于测试的不可变对象。详解Record语法、with表达式用法及在领域模型、数据传输中的应用优势,提升代码健壮性与可维护性,值得收藏。

CompiTide的博客 443

JAVA程序设计--对象和类(八)

不可变对象和类如果一个类是不可变的,那么他的所有数据域必须是私有的,而且没有对任何一个数据域提供公共的set方法。但反过来,却不是一定成立!实例:使用getDateCreated()方法返回数据域dateCreated。它是对Dtae对象的一个引用。通过这个引用,可以改变dateCreated的值。(修改器在Date类里)所以要想一个类成为不可变的,必须要:①所有数据域必须是私有的②没有修改器(s...

我真的太想进步了~tx 242

实现不可变类如何禁止子类化?

实现不可变类时要求禁止子类化。本文先讲禁止子类化的方式,最后解释为什么要禁止子类化。 JDK版本:oracle java 1.8.0_102 如何禁止子类化常用姿势最简单的手段是将类声明为final,如String、Integer等常用的值类。但这样缺乏灵活性:不仅禁止了用户的子类化,开发者也无法利用子类化减少编码工作。 尽管这种手段完全没有变通,却是我们使用最多的一种。只有你需要上述灵活性

程序猿说你好 739

Java 14 Record为何禁止setter?:深入剖析其语义约束与设计哲学

掌握Java 14记录类设计精髓,破解为何禁止setter的方法与原理。本文解析Record不可变语义、适用场景及核心优势,深入探讨其使用限制背后的设计哲学,提升代码安全性与简洁性,值得收藏。

FuncLens的博客 779

<7> 场景图形的工作机制 - 1

Referenced 、ref_ptr、osg::NodeVisitor 顶点访问器示例代码 纹理访问器示例代码 节点访问器示例代码

liangfei868的博客 1498

Java Record 记录

Java中record记录的简单介绍。

m0_74963444的博客 633

惊掉下巴!JS 经典封装竟藏致命漏洞?一行代码拿到私有对象,原型链攻击太狠了!

JS经典封装漏洞揭秘:原型链攻击可获取私有对象 摘要:本文揭露了JavaScript中利用IIFE+闭包实现数据封装的致命漏洞。研究发现,通过原型链特性,攻击者可以在不修改原代码的情况下,仅用一行代码获取内部私有对象并随意修改。漏洞原理是利用Object.prototype的全局继承性和访问器属性的this指向特性。防御方案包括严格key校验、冻结对象或创建无原型对象。文章警示开发者:JS封装没有绝对安全,必须深入理解语言底层机制并做好输入校验,才能编写真正健壮的代码。

weixin_56334307的博客 552
上一篇: DNS的由来
下一篇: java中被final修饰的属性是无法改变的?
大锤997
博客等级 码龄6年 4粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值