int max = obj.getMax();
int max = obj.max;
第二种写法不是更简单,更好理解?
1
Macolor21 2022-08-11 08:52:16 +08:00 via iPhone 2
面向对象
|
2
xxxxxiong 2022-08-11 08:53:55 +08:00 via Android
访问控制
|
4
chendy 2022-08-11 08:56:19 +08:00 1
java 世界的习惯,关注抽象(能 get/set 数据)而不是实现(有对应的字段保存数据)
好处是 get/set 方法里可以放逻辑,比如校验,比如 get 到一个计算出的数据,set 里修改多个字段 缺点是写起来确实麻烦,于是有了 lombok ,还有 kotlin 这种带语法糖的 |
6
zed1018 2022-08-11 08:59:25 +08:00
教条主义罢了,后来 kotlin 的 data class ,java 的 record 类型都放弃了 getter setter 。甚至 kotlin 把 java 里的 getter/setter 都翻译成 field 访问了。
|
7
chaleaochexist 2022-08-11 08:59:36 +08:00
我不是 java 程序员.
========= spring 或者是 spring 之前 EJB 带进来的概念. 美其名曰 java bean. |
8
liufish 2022-08-11 08:59:57 +08:00
@dxatgp02
getMax()里面可能加一些方法,例如如果 max 是个 obj getMax() { if (max == null) { // 异常逻辑,日志啥的 } } 按照你的需要,业务需求来弄。 直接 public 的 max 也是 ok 的其实。看你们的习惯和代码规范了。 |
9
chaleaochexist 2022-08-11 09:00:12 +08:00
问下楼主是不是也是非 Java 程序员?
|
10
zed1018 2022-08-11 09:00:40 +08:00
即便不说后来的新东西,就是 java 里鼎鼎大名 lombok 的最主要的功能之一不就是生成这个吗。说到底就是大家都不乐意写,但是好像你不写显得就很不 pro 一样。
|
11
twofox 2022-08-11 09:04:25 +08:00 1
@dxatgp02 一个成员变量,我想在 set 的时候进行校验 /业务处理 /格式转换
那我是不是写个方法,obj.setValue() 但是总不能让别人改了随便赋值啊,得按照我的 setValue()来赋值,不然数据不对,那我设置为 private 很正常吧? 那我都设置为 private 了,你还怎么 int max = obj.getMax()? |
12
yfugibr 2022-08-11 09:04:42 +08:00 via Android
@dxatgp02 get 和 set 可以对操作自定义,也可以分别赋予不同的权限,读写分离,限制了必须使用显式的赋值方法( set ),防止不经意的修改
|
13
zhuweiyou 2022-08-11 09:04:50 +08:00 4
getMax 里面还能写逻辑, 或者 只读.
如果你 obj.max 可能被 写入. |
14
yule111222 2022-08-11 09:05:17 +08:00
没有任何意义。。。封装不是这么用的 2333
|
15
xiangyuecn 2022-08-11 09:05:40 +08:00 3
又长又臭,所以交给编译阶段去生成这些玩意,源码里眼不见为净
|
16
Macolor21 2022-08-11 09:06:24 +08:00 via iPhone 1
再说一个,封装。如果还说教条主义,还是不理解,那下面:
如果你是刚入门,看 Java 编程思想。 如果已经是老手,学会自己寻找答案 JavaBean 规范本身没问题,问题只在于语言级别没有语法糖,Java 17 加了 record |
17
Building 2022-08-11 09:06:37 +08:00
写多了你就会发现,getter 和 setter 就是很有必要,很多语言你看到的 obj.max 也是在编译阶段帮你自动生成 getter ,当然你可以不用,但是一般语言都会有提供,有的甚至还有 willSet ,set ,didSet ,就算不提供,重复代码多了你也会自己写 getter 方法的
|
18
ligiggy 2022-08-11 09:06:41 +08:00
如果你是库作者,getter/setter 的好处是你封装的代码给别人用的时候体现的。
如果你只是自己用用,如果 ide 或者没有插件支持自动生成 getter/setter ,我觉得完全可以不用。 当然,如果你写 C#,属性是真的香惨了。 |
19
noe132 2022-08-11 09:07:16 +08:00 via Android 14
因为 java 没有像 C#的 getter/setter 只能用方法来模拟
|
20
makelove 2022-08-11 09:08:21 +08:00
|
21
CodeCodeStudy 2022-08-11 09:09:23 +08:00
Java 的成员变量没有多态
|
22
nothingistrue 2022-08-11 09:10:19 +08:00
@dxatgp02 #3 先把 public 、private 、protectce 、default/friend 这几个可见范围搞清楚再说。max 声明称 public ,就可以用你的第二种写法。只不过 public 的字段,要比繁琐的 getter/setter 不便处更大。
|
23
Macolor21 2022-08-11 09:10:45 +08:00 via iPhone
@zed1018 张嘴就来,record 可不可变啊?普通对象可不可变的啊?不可变的对象随便你怎么 public ,怎么访问成员变量,都没问题,它是 final
不要管中窥豹,井底之蛙,如果你是写 Java ,只能说你面向对象的思想都没理解。如果你不是,那只能说你工程化能力挺差 |
24
cmdOptionKana 2022-08-11 09:12:01 +08:00
@noe132 真相了,最根本的原因就是设计语言时没考虑周到,后来只能用方法来模拟。
|
25
yolee599 2022-08-11 09:12:27 +08:00 3
java 没有 getter/setter 只能这样做,去看看 C# 的 getter/setter 就感觉很优雅。
|
26
wanguorui123 2022-08-11 09:13:28 +08:00
设计问题,就和 JAVA 泛型一样,难用
|
27
nba2k9 2022-08-11 09:15:22 +08:00 1
这边建议您重新设计门语言呢
|
28
CodeCodeStudy 2022-08-11 09:16:45 +08:00
class Person {
protected String name = "匿名"; public String toString() { return name; } } class Zhangsan extends Person { protected String name = "张三"; } Person zhangsan = new Zhangsan(); System.out.println(zhangsan); 比如这个例子,想重写 name 是达不到目的的,必须要重写 toString() |
29
zed1018 2022-08-11 09:17:40 +08:00
@Macolor21 笑死,你写 getter setter 不也是能让对象 mutable ,都是 mutable ,我为啥一定要 setter ,脱裤子放屁吗?有多少人写的对象没有 setter ?有多少 javaer 写 allargs ?可真就是张口就来呢。
|
30
dxatgp02 OP 说用 set get 补权限这种说法不感觉很怪吗?这是设计时的问题
同样的对象 public int mx; 和一个有 get set 的对象; 通过入参传到 A.class 里 只能 get 不能 set 传过入参传到 B.class 里 就又能 get 又能 set |
31
yaphets666 2022-08-11 09:19:56 +08:00 1
见人说人话,见鬼说鬼话。每个语言有自己的套路
|
32
beisilu 2022-08-11 09:21:31 +08:00
所以有人说一下 c#的 getter ,setter 是啥样的吗
|
33
cslive 2022-08-11 09:28:22 +08:00 1
那个只是规范,你不遵守也行,不会影响你写程序
|
34
djoiwhud 2022-08-11 09:29:05 +08:00 via Android 2
我个人怀疑最主要的原因是以前没有很强的引用查找。直接访问变量的地方太多,调整的时候,改起来麻烦。
c#的 get,set 一样的冗余。现在写 c#的游戏开发者似乎很少这么写。 |
36
cheng6563 2022-08-11 09:31:21 +08:00
就是教条主义,只是一开始这样随便定了下,然后一些官方库都用 get/set 了,然后第三方库都改成读写 get/set 而不是读写 field 了,然后后面的代码也必须用 get/set 了。
|
37
dqzcwxb 2022-08-11 09:31:57 +08:00 12
我不理解==教条主义
|
38
iseki 2022-08-11 09:33:07 +08:00 via Android
用 Kotlin 吧,简单来说就是语言没有 property ,但是实际发现没 property 不行,就搞出来了手动 property 的 getter setter
|
39
lyxeno 2022-08-11 09:33:32 +08:00
用的最多的控制部分字段只读..只写 get 不写 set 方法,有些 bean 字段很多,get set 方法就显得又臭又长了。还好有 lombok
|
40
frank1256 2022-08-11 09:35:18 +08:00
@dxatgp02 作用域,你写的自己的业务代码,没有问题。如果你是 spring 这样的开源框架,你就要控制好属性的作用域,例如 spring 提供给了你一个类,只给你构造方法可以修改属性,不提供 get ,set 。这样你是没有权限去改他的属性的,限制你的操作,更多的是防止人为操作导致报错。其次是,赋值属性的时候,经常需要校验参数的。如果写成 public ,就没有这些限制了。当然有些简单场景写 public 也没问题
|
41
qwertty01 2022-08-11 09:36:16 +08:00 1
不知道对一个十几年的老语言讨论个什么劲。
很明显就是历史遗留问题。 现在的新程序员这么厉害了嘛?啥都不了解上来直接开始扯淡。 不过新程序员连个 java17 的 record 都不知道,真是世风日下。 |
42
iseki 2022-08-11 09:36:17 +08:00 via Android
直接用 field 意味着没有插入逻辑的机会,内部细节被直接暴露出去了。举个例子当你用动态代理时怎么办呢,field 就无法被代理
|
43
Miy4mori 2022-08-11 09:36:21 +08:00 2
钓鱼贴咋这么多人回复。。。
|
44
cedoo22 2022-08-11 09:36:52 +08:00
面向对象 3 大特征之一, 封装。java 没有‘只读’关键字,
对 pojo 来说,确实不方便,所以,有了 lombk 这玩意。 对于关系复杂对象来说,很有 必要。 动不动就抠帽子, 显得很 S * |
45
LeegoYih 2022-08-11 09:38:14 +08:00
这也能争起来,感觉大家工作都不太饱和
|
46
magicyao 2022-08-11 09:38:35 +08:00 5
@beisilu 成员属性 get 和 set
1 、远古写法( C++) public class Stduent { string name; public string getName() { return name; } public void setName(string name) { this.name = name; } } 2 、中古写法 private string _Name; public string Name { get { return _Name; } set { _Name = value; } } 3 、近代写法 public string Name { get { return Name; } set { Name = value; } } Lambda 写法 public string Name { get => Name; set => Name = value; } 4 、懒狗写法 public string Name{get; set;} |
47
daimubai 2022-08-11 09:41:03 +08:00
做访问控制和参数校验,以及避免误操作。从你举的例子来说有没有 get/set 是没多大意义的。
|
48
oneisall8955 2022-08-11 09:41:49 +08:00 via Android
是的,你想咋样就咋样
|
49
wolfie 2022-08-11 09:42:49 +08:00
封装、继承、多态
子类可以 override 父类的 getxxx() |
50
TateLiao 2022-08-11 09:43:26 +08:00 1
1. getter/setter ,可以在里面添加其他逻辑,例如校验、错误处理等等。假设人对象,有个 age 属性,不通过 setter ,随便赋值,1000 合理吗?
2. getter/setter ,从封装上来说,使用者有必要知道对象里封装了什么吗?通过 getter 去访问,允许暴露被外部的细节不更合适吗? setter 同理 3. getter/setter ,可对字段控制访问级别。例如:get 公开,set 私有 /保护 |
51
Oktfolio 2022-08-11 09:43:58 +08:00
那 JavaScript 这么丑陋的 proposal 是为了啥? https://github.com/tc39/proposal-class-fields
|
52
Oktfolio 2022-08-11 09:44:51 +08:00 1
Java 只是缺少了 getter setter 的语法糖
|
53
RedBeanIce 2022-08-11 09:47:07 +08:00
13 楼是对的
|
54
shenjinpeng 2022-08-11 09:47:32 +08:00
对 public 属性意义不大 , 但是你即想给别人用属性, 又不想让别人改 , 就得 private 封装一下, 提供方法给别人访问属性
|
55
Leviathann 2022-08-11 09:47:35 +08:00
@chaleaochexist 那为什么 C#和 js 都要做 get 和 set 关键字来实现这个行为但是简化一些,而不是直接暴露出去?
|
56
Leviathann 2022-08-11 09:49:50 +08:00
|
57
wolfie 2022-08-11 09:52:20 +08:00
为什么一帮 Java 0 基础的在抢答。
|
58
listenerri 2022-08-11 09:52:50 +08:00
为长远计,避免以后要对成员变量做改动时,需要修改外部代码,所以干脆全用方法封装一下
|
59
dvsilch 2022-08-11 09:53:54 +08:00 3
getter setter 是合理的
不合理的是创建一个私有属性_property ,再用一个没有任何逻辑的 getter setter 去获取修改这个私有属性 |
60
chrisia 2022-08-11 09:55:56 +08:00
getter setter 能放逻辑,没有其他意义。因为 java 一开始没有语法层面的支持,所以只能写 getter setter 这种冗余的代码。现代语言例如 kotlin 直接在语法层面提供 getter setter 。
|
61
xiao109 2022-08-11 09:56:19 +08:00 2
我不喜欢的一律都是垃圾
|
62
Edsie 2022-08-11 09:57:35 +08:00
Getter 、Setter 是标准的 Java Bean 定义写法
比如常见的 JSON 序列化,就是根据 Bean 定义进行转换的,也就是说即使没有 field 但是有个 getter 方法,也能序列化出这个字段 |
63
chrisia 2022-08-11 09:58:07 +08:00
@chrisia 也就是说,多数情况下认为 getter setter 是没有处理逻辑的(事实也是如此,你很少会在对字段操作的时候塞逻辑,特别是 data class 这种对象),少数情况下用特定的 getter setter 语法去处理。
|
64
startisan 2022-08-11 09:59:15 +08:00
getter setter 根本就不是面向对象啊
https://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html |
65
Edsie 2022-08-11 10:00:21 +08:00
根本不是说,你需要写 getter setter
而是当你需要这个对象是一个 Java Bean 的时候,你就要符合 Java Bean 定义 |
66
pkoukk 2022-08-11 10:02:57 +08:00
c#的 getter 和 setter 就很优雅
可以直接使用 n1 = obj.Max ,obj.max=n1 但是如果只有 getter ,而你尝试 obj.Max=1 ,编译器会报错 |
68
chrisia 2022-08-11 10:09:16 +08:00
@chrisia 还有一点比较重要,getter setter 可以有不同的访问级别,不过还是那句话,这些都是少数情况,我认为针对少数情况做处理才是好的选择,而不是迫使所有字段都采用 getter setter 。
|
69
zzzzz001 2022-08-11 10:10:05 +08:00
把控制权永远留给自己,大家维护多了,需求多了,业务复杂了,就知道这种好处了
|
70
yuezk 2022-08-11 10:13:21 +08:00 1
@pkoukk #66 是,但是本质上还是要提供 setter/getter 来操作内部的字段,C# 提供了一个比较好用的词法糖。
类似的,JS 也支持 setter 和 getter ,但使用上还是和 C# 一样,直接用点操作符。 |
71
zhangchongjie 2022-08-11 10:14:27 +08:00 2
一般.set .get 的原因是变量 private ,你该问为什么对象内要有私有属性, 如果都是 public 哪还需要,建议重学,别在这丢人现眼
|
72
dxatgp02 OP @dvsilch 就是这意思,就实体类还要写大量 set get.如果不想写用代码生成或 lombok. 不合理但不能问,问就是不喜欢不理解.
|
73
yuezk 2022-08-11 10:23:23 +08:00 5
搬运一个 SO 的回答,如果楼主真想了解的话可以点过去看看,就不在这里重复了,而且说的还没有人家好。https://stackoverflow.com/questions/1568091/why-use-getters-and-setters-accessors
如果你觉得使用 obj.setName() 不如使用 obj.name 方便,那只是语法层面的问题,和 geter/setter 无关。比如 C# 中就使用这种点操作符,但它底层还是会调用 setter/getter 的。 |
74
fkdog 2022-08-11 10:24:31 +08:00
其实 b=a.getB() / a.setB(b) 这种写法完全可以替代成 b=a.B / a.B=b
|
75
neochen13 2022-08-11 10:26:49 +08:00
kotlin 可解
|
76
qq1009479218 2022-08-11 10:31:05 +08:00
充血模型
|
77
lisongeee 2022-08-11 10:32:14 +08:00 2
楼主的问题也可以是 java 为什么要写 99% 都用不到的 额外的 空的 一堆什么也不干的 setter/getter
|
78
shijingshijing 2022-08-11 10:32:35 +08:00
|
79
Cbdy 2022-08-11 10:35:29 +08:00 via Android
可以作为方法引用,另一方面,方便调试
|
80
lancelock 2022-08-11 10:36:55 +08:00
你可以学学其他语言,尤其是比较新的一些,看看对这部分的处理。多看多用多比较自然就知道各种语言特性的用意在哪里
|
81
freefcw 2022-08-11 10:38:30 +08:00
getter 和 setter 只是细节,关键的思想在于封装,至于用 gotter 还是 sotter,还是省略前缀,都是实现的细节
换句话说盖个房子要不要外墙上瓷砖,不上瓷砖当然也可以住人,你要觉得罗嗦花钱,那就是你的事情,但你要说瓷砖没用,那就是你的认知问题了,毕竟窑洞也可以住人,盖房子做啥 |
82
skinny 2022-08-11 10:49:07 +08:00 5
getter 和 setter 作用都不理解的(这不是 Java 特有的),我只能说在红利期程序员这碗饭太好吃了,不过看互联网公司这裁员势头,红利期也差不多过了,你不被优化谁被优化
|
83
yaphets666 2022-08-11 10:50:14 +08:00 2
@skinny 被优化的都是和领导关系不好的,和技术没关系
|
84
dxatgp02 OP 能回答问题的寥寥无几,人浮于事却不少.
|
85
lovedoing 2022-08-11 10:56:31 +08:00
建议使用 groovy 全局 public [狗头]
|
87
devswork 2022-08-11 11:05:49 +08:00
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 判断了,且后期修改的时候(比如又加入了个“中性”),只需要改动这一处,而不需要处处改动 |
88
Kasumi20 2022-08-11 11:08:19 +08:00
所以 Kotlin 好用啊,不关注这个东西就用默认的,需要的时候才去定义
|
89
devswork 2022-08-11 11:08:42 +08:00
#87 还忘了一句:我不希望这个性别 gender 被别人乱改,而我却不知道改成了什么样子,所以我只对外暴露 getter setter ,防止他们乱改( private int gender ),别人只能通过我定义的 getter setter 来修改值,这些值必定是合法的才能修改成功,也必定是我知道的,因为调用了我写的 getter setter 。
|
90
devswork 2022-08-11 11:14:08 +08:00
我怀疑是不是来赚金币的!!!!!!!
|
91
justNoBody 2022-08-11 11:21:51 +08:00
我觉得这个问题很有意思。我从一开始写 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 的历史进程中,这到底是如何演变出来的,这一点我非常好奇,如果有知道的朋友请艾特我,感谢。 |
92
javaisthebest 2022-08-11 11:22:14 +08:00
|
93
dcsuibian 2022-08-11 11:29:45 +08:00 via Android 1
js 、python 、C#也有 Getter/Setter ,只是写法更像变量
楼主问的是“Java 对象里为什么要 get set”,而不是“Java 为什么要采用目前 Getter Setter 的显示写法” |
94
dxatgp02 OP @javaisthebest 业务逻辑是必须要包装有些还要通过事务来保障,但写大量无用 set get,再用 lombok 来折中.不奇怪吗?
那种语言告诉我们没有业务逻辑,只用语法就可以解决.业务逻辑必须包装,但不要包装的东西强行包装,就很怪. |
95
hez2010 2022-08-11 11:37:21 +08:00 via Android
尽管 class 中可能确实不需要 getter/setter 这种东西,但是如果你将多个有同样行为的类型抽象成一个 interface 的时候,就需要 getter 和 setter 了,因为 interface 不能定义字段,它解决了 C++多继承 /菱形继承带来的字段覆盖问题的。
|
96
sunmker 2022-08-11 11:47:17 +08:00
面向对象:封装、继承、多态
|
97
git00ll 2022-08-11 11:47:56 +08:00
obj 如果是代理类,这两个就有区别了
|
98
zmal 2022-08-11 11:53:18 +08:00
op 好奇的可能是为什么纯数据实体也要用 getter/setter ,这要从 Java 的一切皆对象说起了,涉及到当时的语言设计思想,略过不表。
本质上是因为在 Java 中没有结构体这种纯数据实体结构,jdk17 的 record 也只是对象的语法糖。结构体可能在 jdk18 或 19 加入。 |
99
glfpes 2022-08-11 11:53:51 +08:00
语法糖,我不认为是好的设计
少打 2 个字真的不会让你早几分钟下班。反而读各种不同风格的代码会让你晚几分钟下班。 |
100
luhe 2022-08-11 11:54:10 +08:00 via iPhone 1
还是看看远处的业务逻辑吧家人们
|