int max = obj.getMax();
int max = obj.max;
第二种写法不是更简单,更好理解?
![]() | 1 Macolor21 2022-08-11 08:52:16 +08:00 via iPhone ![]() 面向对象 |
2 xxxxxiong 2022-08-11 08:53:55 +08:00 via Android 访问控制 |
![]() | 4 chendy 2022-08-11 08:56:19 +08:00 ![]() 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 ![]() @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 ![]() getMax 里面还能写逻辑, 或者 只读. 如果你 obj.max 可能被 写入. |
14 yule111222 2022-08-11 09:05:17 +08:00 没有任何意义。。。封装不是这么用的 2333 |
![]() | 15 xiangyuecn 2022-08-11 09:05:40 +08:00 ![]() 又长又臭,所以交给编译阶段去生成这些玩意,源码里眼不见为净 |
![]() | 16 Macolor21 2022-08-11 09:06:24 +08:00 via iPhone ![]() 再说一个,封装。如果还说教条主义,还是不理解,那下面: 如果你是刚入门,看 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 ![]() 因为 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 ![]() 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 ![]() 这边建议您重新设计门语言呢 |
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 ![]() 见人说人话,见鬼说鬼话。每个语言有自己的套路 |
![]() | 32 beisilu 2022-08-11 09:21:31 +08:00 所以有人说一下 c#的 getter ,setter 是啥样的吗 |
33 cslive 2022-08-11 09:28:22 +08:00 ![]() 那个只是规范,你不遵守也行,不会影响你写程序 |
34 djoiwhud 2022-08-11 09:29:05 +08:00 via Android ![]() 我个人怀疑最主要的原因是以前没有很强的引用查找。直接访问变量的地方太多,调整的时候,改起来麻烦。 c#的 get,set 一样的冗余。现在写 c#的游戏开发者似乎很少这么写。 |
![]() | 35 DonaidTrump 2022-08-11 09:29:47 +08:00 via iPhone @dxatgp02 没错,就是这样 |
![]() | 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 ![]() 我不理解==教条主义 |
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 |
![]() | &nbs; 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 ![]() 不知道对一个十几年的老语言讨论个什么劲。 很明显就是历史遗留问题。 现在的新程序员这么厉害了嘛?啥都不了解上来直接开始扯淡。 不过新程序员连个 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 ![]() 钓鱼贴咋这么多人回复。。。 |
![]() | 44 dr1q65MfKFKHnJr6 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 ![]() @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 itechify PRO 是的,你想咋样就咋样 |
![]() | 49 wolfie 2022-08-11 09:42:49 +08:00 封装、继承、多态 子类可以 override 父类的 getxxx() |
![]() | 50 TateLiao 2022-08-11 09:43:26 +08:00 ![]() 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 ![]() Java 只是缺少了 getter setter 的语法糖 |
![]() | 53 RedBeanIce 2022-08-11 09:47:07 +08:00 13 楼是对的 |
![]() | 54 urlk 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 ![]() 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 ![]() 我不喜欢的一律都是垃圾 |
![]() | 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 ![]() @pkoukk #66 是,但是本质上还是要提供 setter/getter 来操作内部的字段,C# 提供了一个比较好用的词法糖。 类似的,JS 也支持 setter 和 getter ,但使用上还是和 C# 一样,直接用点操作符。 |
71 zhangchongjie 2022-08-11 10:14:27 +08:00 ![]() 一般.set .get 的原因是变量 private ,你该问为什么对象内要有私有属性, 如果都是 public 哪还需要,建议重学,别在这丢人现眼 |
![]() | 72 dxatgp02 OP @dvsilch 就是这意思,就实体类还要写大量 set get.如果不想写用代码生成或 lombok. 不合理但不能问,问就是不喜欢不理解. |
73 yuezk 2022-08-11 10:23:23 +08:00 ![]() 搬运一个 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 BearCookie 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 ![]() 楼主的问题也可以是 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 ![]() getter 和 setter 作用都不理解的(这不是 Java 特有的),我只能说在红利期程序员这碗饭太好吃了,不过看互联网公司这裁员势头,红利期也差不多过了,你不被优化谁被优化 |
![]() | 83 yaphets666 2022-08-11 10:50:14 +08:00 ![]() @skinny 被优化的都是和领导关系不好的,和技术没关系 |
![]() | 84 dxatgp02 OP 能回答问题的寥寥无几,人浮于事却不少. |
![]() | 85 JsonNode 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 ![]() 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 pikaconan 2022-08-11 11:54:10 +08:00 via iPhone ![]() 还是看看远处的业务逻辑吧家人们 |