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

2022 年 8 月 11 日
 dxatgp02

int max = obj.getMax();

int max = obj.max;

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

19357 次点击
所在节点    Java
185 条回复
freefcw
2022 年 8 月 11 日
getter 和 setter 只是细节,关键的思想在于封装,至于用 gotter 还是 sotter,还是省略前缀,都是实现的细节

换句话说盖个房子要不要外墙上瓷砖,不上瓷砖当然也可以住人,你要觉得罗嗦花钱,那就是你的事情,但你要说瓷砖没用,那就是你的认知问题了,毕竟窑洞也可以住人,盖房子做啥
skinny
2022 年 8 月 11 日
getter 和 setter 作用都不理解的(这不是 Java 特有的),我只能说在红利期程序员这碗饭太好吃了,不过看互联网公司这裁员势头,红利期也差不多过了,你不被优化谁被优化
yaphets666
2022 年 8 月 11 日
@skinny 被优化的都是和领导关系不好的,和技术没关系
dxatgp02
2022 年 8 月 11 日
能回答问题的寥寥无几,人浮于事却不少.
JsonNode
2022 年 8 月 11 日
建议使用 groovy 全局 public [狗头]
meteor957
2022 年 8 月 11 日
@skinny 你说话感觉好恶心啊,你现实生活中也这样么
devswork
2022 年 8 月 11 日
int gender = -1; //-1 未定义,1 男,2 女

getGender(){
return this.gender;
}

getGenderReadable(){
if(this.gender == -1){
return "未定义";
}
if(this.gender == 1){
return "男";
}
if(this.gender == 2){
return "女";
}
return "未知";
}

setGender(int g){
if(g == 1 || g == 2){
this.gender = g;
}else{
// 非法的值,需要异常处理...
}
}

至少我这种非法值的判断、可读性的返回值,我写一次代码就够了,就不用在调用方各种 if else 判断了,且后期修改的时候(比如又加入了个“中性”),只需要改动这一处,而不需要处处改动
Kasumi20
2022 年 8 月 11 日
所以 Kotlin 好用啊,不关注这个东西就用默认的,需要的时候才去定义
devswork
2022 年 8 月 11 日
#87 还忘了一句:我不希望这个性别 gender 被别人乱改,而我却不知道改成了什么样子,所以我只对外暴露 getter setter ,防止他们乱改( private int gender ),别人只能通过我定义的 getter setter 来修改值,这些值必定是合法的才能修改成功,也必定是我知道的,因为调用了我写的 getter setter 。
devswork
2022 年 8 月 11 日
我怀疑是不是来赚金币的!!!!!!!
justNoBody
2022 年 8 月 11 日
我觉得这个问题很有意思。我从一开始写 Java 就一直是保持这个习惯,确实没有去思考过为什么要这么写。
我查了一些资料:
- https://javarevisited.blogspot.com/2012/03/private-in-java-why-should-you-always.html#axzz7bcbsXwnO
- https://www.quora.com/Why-do-we-use-get-and-set-methods-to-access-variables-in-java-instead-of-using-them-directly
- https://www.infoworld.com/article/2073723/why-getter-and-setter-methods-are-evil.html?page=2
- https://www.freecodecamp.org/news/java-getters-and-setters/

在我看来,使用 set 和 get 方法的好处有以下几点:

1. 字段的读写权限可以更细化,如一个字段仅允许同包下的其他类去写,但是读是 public
2. 可以在 set 方法中增加一些字段的约束判断,比如 set null 时候,修改为 0 等,或者是 get null 时候,返回一个“-“的字符等等

落地到实际开发,第一点我并没有看到过有人这么用,基本上 set 和 get 方法都是 public

我也同意大家说的 get 和 set 方法可能只是缺少了一个语法糖,因为我也有用 lombok 去减少这部分的代码量

除此此外,我认为这应该是 Java 的一个规范,或者是最佳实践,因为在很多框架做反射的时候,都不约而同的用到了 set 方法。比如 jackson 的反序列化。

但是我并没有找到相关的文档,不知道在 Java 的历史进程中,这到底是如何演变出来的,这一点我非常好奇,如果有知道的朋友请艾特我,感谢。
javaisthebest
2022 年 8 月 11 日
@dxatgp02 😓也没见你对于别人回答的见解和疑问啊
@TateLiao 这个人的答案你回答下?
dcsuibian
2022 年 8 月 11 日
js 、python 、C#也有 Getter/Setter ,只是写法更像变量
楼主问的是“Java 对象里为什么要 get set”,而不是“Java 为什么要采用目前 Getter Setter 的显示写法”
dxatgp02
2022 年 8 月 11 日
@javaisthebest 业务逻辑是必须要包装有些还要通过事务来保障,但写大量无用 set get,再用 lombok 来折中.不奇怪吗?
那种语言告诉我们没有业务逻辑,只用语法就可以解决.业务逻辑必须包装,但不要包装的东西强行包装,就很怪.
hez2010
2022 年 8 月 11 日
尽管 class 中可能确实不需要 getter/setter 这种东西,但是如果你将多个有同样行为的类型抽象成一个 interface 的时候,就需要 getter 和 setter 了,因为 interface 不能定义字段,它解决了 C++多继承 /菱形继承带来的字段覆盖问题的。
sunmker
2022 年 8 月 11 日
面向对象:封装、继承、多态
git00ll
2022 年 8 月 11 日
obj 如果是代理类,这两个就有区别了
zmal
2022 年 8 月 11 日
op 好奇的可能是为什么纯数据实体也要用 getter/setter ,这要从 Java 的一切皆对象说起了,涉及到当时的语言设计思想,略过不表。

本质上是因为在 Java 中没有结构体这种纯数据实体结构,jdk17 的 record 也只是对象的语法糖。结构体可能在 jdk18 或 19 加入。
glfpes
2022 年 8 月 11 日
语法糖,我不认为是好的设计
少打 2 个字真的不会让你早几分钟下班。反而读各种不同风格的代码会让你晚几分钟下班。
pikaconan
2022 年 8 月 11 日
还是看看远处的业务逻辑吧家人们

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

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

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

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

© 2021 V2EX