试图从Java设计者角度思考getter/setter的作用
当大家初学Java时,很容易看到或听到这样的观点:“在开发中, 为了避免出现逻辑错误, 我们建议对所有属性进行封装,并为其提供setter及getter方法进行设置和取得操作。”
有句话讲的好“说时似悟,对境生迷“,我们自以为理解了一个道理,但真正用它的时候却开始懵逼。
当我开始第一次编写子类,加上getter/setter 方法时,就黑人问号.jpg了。public修饰属性的设置方式是“对象名.属性 = 赋的值“,获取方式则是直接对象名.属性;private修饰是通过”对象名.set属性(赋的值)”,获取则是”对象名.get属性”。那不还是可以谁想用谁用,谁想拿就拿吗?脱了裤子放屁,多此一举?那说好的安全性、避免错误不是唬人的吗?
这么看来getter/setter 方法就只剩编码规范一种用途了吧?后来回想老师说的,避免逻辑错误,指的是对异常数据的处理。
初级版本:
public void setAge(int a){
if(a>0&&a<150)
age = a;
}
让使用者设置的age在(0,150)的区间内。
高级版本:
setAge (int age){
if(age<1||age>120)
throw new Exception("你输入的年龄不合法");
}else{
this.age = age;
}
age不光设置区间,甚至还有错误提示
)
两个版本作用都是一样,这个限制功能确实是public无法做到的,那么现在看来,对数据进行限制,貌似是getter/setter 方法的唯一不同了。
但网友的力量是强大的,在一篇类似话题的文章下面有这么一句评价:
原来老师说的也不是对的啊。。。所谓数据异常处理,在Java的高内聚低耦合设计理念下,也是应该交给专门的校验类,而不是setter方法去做。所以private加上getter/setter 方法,在本质上跟public没有区别,同时,public也可以加上getter/setter 方法,很多框架设计甚至就是如此要求的。getter/setter 方法的唯一价值就是保证代码的一致性,规范性,就好像让整个项目如仪仗队般整齐,没有其他价值。后续又可以从阿里巴巴Java编程规范验证这一点:
出自《码出高效》阿里巴巴Java开发手册 1.4.0,一、编程规约—(四)OOP规约第17条。这条规约的条目是“推荐“级,也就不是强制要求,个人理解为,Java设计者当初添加getter/setter方法其实也是想要它可以实现数据异常处理功能的,但是在后人的使用中,因为考虑到排查问题难度的问题,就逐渐废弃了这个功能。
同时我想Java设计者设计getter/setter 方法的主要用途大概是在于“只读/只写功能”,有些属性在构造对象完成,如果是只读,那么就需要把属性设置为private同时添加一个getter方法,如果只写,那就添加一个setter方法。
说了这么多,getter/setter方法的理解总结起来两点:
保证代码的规范性和一致性。
服务于只读/只写属性。
这篇文章很大程度上参考这位https://blog.youkuaiyun.com/llittlebird001/article/details/52725245大神所写,我很喜欢他说的:不要不去考虑为什么这么做,不然我们也会沦为工具。
同样,如果getter/setter方法网友们还有什么可以补充的,也非常欢迎指出。