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