当前位置: 首页 > news >正文

Java封装过程中的getter/setter究竟有什么用?

一、没有 get/set 的世界(直接暴露字段)

假设你有一个表示 “银行账户” 的类,直接把余额 balance 暴露给外部:

public class BankAccount {// 余额直接暴露,任何人都能修改public double balance; 
}// 外部代码
BankAccount account = new BankAccount();
// 问题1:可以直接修改余额(比如偷偷改大)
account.balance = 9999999; 
// 问题2:可以把余额设为负数(逻辑上不合理)
account.balance = -1000; 

问题

  • 外部代码可以随意修改内部数据(比如把余额改到无限大)。
  • 无法阻止非法数据(比如负数余额)。
  • 未来如果想加逻辑(比如修改余额时记录日志),必须改动所有使用这个类的代码

二、有 get/set 的世界(封装字段)

现在用 private 隐藏字段,通过 get/set 控制访问:

public class BankAccount {// 余额私有化,外部无法直接访问private double balance; // 只读:只能获取余额,不能直接修改public double getBalance() {return balance;}// 可控修改:修改余额时必须走这里public void setBalance(double balance) {// 验证逻辑:余额不能为负数if (balance < 0) {System.out.println("余额不能为负!设置失败");return;}// 业务逻辑:修改余额时记录操作(比如日志)System.out.println("修改余额:" + this.balance + " → " + balance);this.balance = balance;}
}// 外部代码
BankAccount account = new BankAccount();
// 情况1:尝试设为负数(被拦截)
account.setBalance(-100); // 输出:余额不能为负!设置失败
// 情况2:正常修改
account.setBalance(1000); // 输出:修改余额:0.0 → 1000
// 情况3:尝试直接修改(编译报错,因为 balance 是 private)
// account.balance = 99999; // 报错:The field BankAccount.balance is not visible

安全点

  1. 数据访问可控

    • 外部只能通过 getBalance() 看余额(只读),通过 setBalance() 改余额(必须走验证)。
    • 想偷改余额?没门,因为 balance 是 private 的。
  2. 非法数据拦截

    • 在 setter 里加逻辑(比如 if (balance < 0)),直接阻止不合理的数据。
  3. 扩展灵活

    • 未来想加功能(比如修改余额时发短信通知),只需要改 setBalance 方法,外部代码完全不用动。

三、生活中的类比(理解封装)

把 BankAccount 类想象成一个真实的银行账户

  • private balance → 你的 “实际余额”(银行内部才能直接碰)。
  • getBalance() → “查询余额”(你能看,但不能改)。
  • setBalance() → “柜台 / ATM 存钱”(必须走银行的流程,比如验证金额、记录操作)。

如果银行允许你直接改余额(像暴露 public balance 那样),世界就乱套了;但通过 get/set(柜台流程),银行就能控制修改的合法性,这就是封装的意义。

四、总结:get/set 如何让代码更安全

  1. 隐藏内部实现:用 private 把字段藏起来,外部无法直接操作。
  2. 控制修改逻辑:在 setter 里加验证、日志、权限检查等逻辑。
  3. 隔离变化影响:未来修改内部逻辑(比如换存储方式),外部代码不用改。

简单说,get/set 不是安全的全部,但它是 “让类自己控制数据如何被访问和修改” 的基础,这就是面向对象中 封装 的核心价值。

如果现在还觉得抽象,记住一个原则:永远让字段是 private 的,用 get/set 当 “门卫” —— 门卫(get/set)能检查每一个想进来(修改数据)的人是否合法。

http://www.lqws.cn/news/491851.html

相关文章:

  • 爬虫003----requests库
  • ABP VNext + Apache Kafka Streams:构建高吞吐、生产级实时流处理服务
  • 自回归(AR)与掩码(MLM)的核心区别:续写还是补全?
  • 采集MFC软件的数据方法记录
  • 【Java面试】你是怎么控制缓存的更新?
  • Linux系统能ping通ip但无法ping通域名的解决方法
  • 【源码+文档+调试讲解】基于web的运动健康小程序的设计与实现y196
  • 【科研绘图系列】R语言绘制论文组合图(multiple plots)
  • 【Leetcode】有效的括号、用栈实现队列、用队列实现栈
  • 数据赋能(313)——合作共享——跨界融合
  • STM32 ADC(DMA)双缓冲采集+串口USART(DMA)直接传输12位原始数据到上位机显示并保存WAV格式音频文件 收藏住绝对实用!!!
  • 马斯克YC技术核弹全拆解:Neuralink信号编译器架构·星舰着陆AI代码·AGI防御协议(附可复现算法核心/开源替代方案/中国技术对标路径)
  • CSS 中aspect - ratio属性的用途及应用
  • Mermaid学习第二部
  • Netty内存池核心:PoolChunkList解析
  • 【附源码】考试报名系统设计与实现+SpringBoot + Vue (前后端分离)
  • 【Linux网络编程】五种IO模型与非阻塞IO
  • 树莓派5+Ubuntu24.04 LTS ROS2 Jazzy安装 保姆级教程
  • transformer-kv缓存
  • Docker健康检查
  • 【AI News | 20250623】每日AI进展
  • 开发Qt程序时,为什么是CMake?
  • 前端截图并导出pdf
  • 基于Django和MySQL的智能图像分类与情感分析系统
  • Nginx-前端跨域解决方案!
  • AI+地图打车:如何用机器学习实现小程序订单智能匹配与路径优化?
  • 征服分布式系统:阿里云 Linux 多机互联与资源共享实战指南
  • 区块链大讲堂 | 分布式隐私计算友好的零知识证明协议
  • 基于PostgreSQL的百度或高德等POI多层级分类的数据库设计
  • [Java恶补day31] 21. 合并两个有序链表