用set get与直接设为public有什么区别
这事我刚学的时候也挺疑惑的。问老师就是说封装性,不要交给外人控制,比如年龄你就要在set里面设置判断条件,不能随便赋值。这么说确实有道理,但至于每个变量都set get一下吗,虽然说编译器好用,但有些时候,我好像直接设置成public也没什么关系。
这个疑惑其实在我心里一直没解开,只是老师这样教,编译器也提供了便捷方法就一直迷迷糊糊的用了,反正大家都这样写。直到刚刚一段不安全的代码才让我重新思考起了这个问题。
为什么用set get
个人认为是先有set,比如说我们有一个age变量,但我们并不希望它被任意赋值。所以我们需要将其设置为private,提供一个set方法防止别人给他赋个1000岁,这不成怪物了吗?有了set之后,你将变量弄成了private别人无法直接访问了,所以又弄了个get。也就是说如果你对变量的赋值有约束的话就应该使用set get,它们就是为了封装而生的。
用了就万事大吉?
用了set get你就真的封装好了?请看代码
public class T {
private List results=new LinkedList<>();
public List getResults() {
return results;
}
public void setResults(List results) {
this.results = results;
}
}
各位觉得有什么问题吗?好像没啥问题,都是这样的,顺手一按编译器就自动生成了。但其实如果你返回的是集合的话,那么这样子形同虚设。
T t=new T();
t.getResults().add("!!!");
t.getResults().clear();
外部修改数据还是这么的随意,如果我们只想让外界读取results,把修改的控制权放在自己手上该如何是好呢?
当然是返回一个不可修改的集合啦:
public List getResults() {
return Collections.unmodifiableList(results);
}
这样我们就将其封装好了。所以不要直接无脑用编译器生成set get,如同上面的例子。你不对get进行调整,就如同一个public,完全没有封装起来。应该结合具体需要,编写set get,这样才符合初衷。