Java 对象里为什么要用 get set?

2022 年 8 月 11 日
 dxatgp02

int max = obj.getMax();

int max = obj.max;

第二种写法不是更简单,更好理解?

19357 次点击
所在节点    Java
185 条回复
kenvix
2022 年 8 月 11 日
因为老 Java 没有 [属性] 只有 [字段] 的概念啊。新 Java 有了 record 在一定程度上解决了这个问题。而 Kotlin 和 C#有 [属性] 的概念,则从根本上解决了这个问题
guoqiao
2022 年 8 月 11 日
这个问题很有代表性.

我刚学编程的时候也疑惑过这个问题(C#/C++). 同样的, 人们给出的也都是封装, 重构, 访问控制之类的理由. 我将信将疑. 但因为当时的我所知甚少, 就姑且信之, 当作是 Good Practice.

直到后来我转向了 Python. 什么狗屁 getter/setter ? 它连 public/ptotected/private 关键字都没有, 默认字段都是 public 的(尽管你可以用比如 __name 来实现 private, 如果你真的需要).

Python 也可以用 @property / @property.setter 来实现一样的访问控制, 但同样, 仅仅是在你*确实*需要的时候.

别看这只是一个小小的语法偏好差异, 但它却启发了我对思维方式的反思:

- 加上 getter/setter 在某些特定情况下能带来一些好处, 那我们强制要求所有的字段都设成 private, 全部加上 getter/setter, 好不好啊 ?

- 面向对象有很多好处, 那我们强制要求万物皆对象, 哪怕是 Hello World, 都要定义在一个 Class 里, 好不好啊 ?

- 设计模式如此精妙, 能解决很多很多常见问题, 那我们把能套上设计模式的地方全部都用上, 要求每个程序员都掌握, 好不好啊 ?

- 既然戴口罩有利于预防流感, 那我们要求所有人都必须戴口罩, 不戴的不让上路, 好不好啊 ?

诸如此类.

我知道很多人会说好, 因为现实生活中有很大一部分人就是习惯别人给自己制定一个一劳永逸一刀切的规范, 然后他无脑跟着执行就行了, so easy.
但也有另一类人, 不喜欢被束缚, 不喜欢被别人的规范所限制, 喜欢自由自在的感觉, 哪怕这个确实会带来一些弊端和损失.

编程语言的选择, 以及是否移民的选择, 也可以借助这个问题一并回答:

如果你是前者, 那么你适合学 Java, 以及生活在国内.
如果你是后者, 那么你适合学 Python, 以及生活在国外.
tf2
2022 年 8 月 11 日
getter 和 setter 是一种 hook 。
javaisthebest
2022 年 8 月 11 日
@dxatgp02

面向六大原则 开闭原则,对扩展开放对修改关闭。

知道什么叫做访问修饰符嘛? 结合访问修饰符不就是实现了开闭原则。

不要包装的东西强行包装? 那请问什么叫做 不需要包装呢?


你是讨厌 用 getter setter 方法 还是讨厌 java 必须要 getter setter 呢?
franklinre
2022 年 8 月 11 日
比如数据库新增字段 Integer maxQusCount ,新增的记录 maxQusCount 默认值是 0 ,那原来的记录的 maxQusCount 就是 null ,此时就可以统一使用 getMaxQusCount(){this.maxQusCount==null?0:this.maxQusCount}
jeehal
2022 年 8 月 11 日
如果这个类的 max 不用了或者要改
项目其他地方写了一堆 xxx.max ,难不难受
guoqiao
2022 年 8 月 11 日
#82: "getter 和 setter 作用都不理解的(这不是 Java 特有的),我只能说在红利期程序员这碗饭太好吃了,不过看互联网公司这裁员势头,红利期也差不多过了,你不被优化谁被优化"

我要特别的替楼主怼一下#82 楼这个回答. 请你不要被他唬住.
有没有可能, 说这类话的人, 不过是因为他们没有经过自己的思考而人云亦云? 会不会是因为他先学了 Java, 甚至只学了 Java, 从而先入为主, 被禁锢在自己的思维茧房里了 ? 能问出最傻最基础问题的人, 会不会才是那个直面本质, 大胆思考, 甚至推倒重来, 开宗立派的人呢 ?
soupu626
2022 年 8 月 11 日
所以说只是少了一个默认的语法糖,默认生成字段的最简 get/set ,有数据校验之类的加强需求,再来手写就完了,lombok 的 @Getter@Setter 做的不也就是这件事么
skinny
2022 年 8 月 11 日
@guoqiao 那就拜托你们这类人务必一直保持对这种基础知识的无知状态,好给别人腾出饭碗呢
soupu626
2022 年 8 月 11 日
另外直接访问字段,然后前后写校验逻辑,为什么不把者些逻辑放到 get/set 里呢,如果校验逻辑改了,是不是要霰弹式修改
soupu626
2022 年 8 月 11 日
@guoqiao 用啥编程语言还上升到思维方式,要不要移民上了。。。。你牛
dxatgp02
2022 年 8 月 11 日
@skinny 别墨鱼划水了,说优化你心不虚吗?
dog82
2022 年 8 月 11 日
我觉得 Java 要符合 OO 里的 OCP 原则,所以设计了 get/set
cenbiq
2022 年 8 月 11 日
回复太乱了,说到底就是“getter/setter”==“属性(prop)”,作用就是对“字段(field)”的访问控制。java 这门语言没有“属性”这个概念,它的做法是用方法包装“字段”强行模拟“属性”。其他更先进的面向对象语言则本身支持“属性”。
ychost
2022 年 8 月 11 日
主要是没有 get/set 语法糖,比如 c# 就很友好地区分了 property 、attribute 、field
qiumaoyuan
2022 年 8 月 11 日
这个问题很简单,你觉得没用就不用。这是标准答案。等到你要用了,自然就知道为什么用。在网上问,最后的结果你也会变成你自己说的“为用而用”。

同样的问题包括:为什么要写测试,为什么要用设计模式,为什么要面向对象。
Reminders
2022 年 8 月 11 日
java 虽然是面向对象设计语言,但是很多人在写业务的时候都是面向过程式的,面向数据库的,对象大多数都是只有 getter setter 的数据对象,并且把大量的业务逻辑放在一个叫 service 的庞大的类中处理,这种没有设计的代码,我写吐了。
Reminders
2022 年 8 月 11 日
@yule111222 #14 同意,这种现象大量出现在面向数据库编程的项目中,这种项目中的很多对象,就在一种数据对象,数据结构,没有承担起作为一个类该有的职责。
realpg
2022 年 8 月 11 日
一堆人说了一大堆好处
然后我翻了公司历史版本库里的各种 getter setter
没有人在 getter setter 里写任何所谓的校验逻辑

查找累计结果 近 18 万个 随机抽选了 50 个,没有一个有逻辑.
Hstar
2022 年 8 月 11 日
我个人对这个问题的回答是:这是 Java 这门语言的基调和 Java 创始人的个人风格导致的,充斥着规范、教条、约定俗成组成的条条框框,它假设使用者是个菜鸡,强迫使用者沿着设计师设计好的方式来堆砌代码。

OOP 思想广泛的来说,使用对象来操作就可以视为 oop ,那么如何操作对象,这就是各个语言充斥着私货的地带了。比如这里提到的这个点,用了 Java 为什么一定要用 Get/Set 来操作对象的属性,我怎么操作你管得着吗,how dare you ?

但从另一个角度来看,这些私货其实每个语言都有,只是或多或少而已。

追根溯源,这个问题是 Java 缺失了对象属性的分类导致的,不区分属性、字段,导致不必要通过 Get/Set 来操作的属性也必须这么玩。可以理解为 Java 的时代局限性或作者的个人口味吧,同理还有类的多继承,等等。

还有想说一句,Java 并不能代表 OOP ,它只是其中一个实现,它的做法不是一定都是对的,都是真理。奉劝楼里的几位井底之蛙 java 程序员多看多想,争取晚点被优化。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://v2ex.ih06.com/t/872064

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX