1、起因
如果为一个private变量设置了get()和set()方法,不就是相当于其为public变量吗?这样做是不是过于繁琐了?
如果对形如下方的简单代码而言,可以说是上面的疑惑是对的
public class SimpleGetAndSet {
private int n;
public SimpleGetAndSet(int n) {
this.n = n;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
}
2、意义
然而既然Java有这样的规范,必有其存在的意义。
2.1、类安全性
从类安全角度出发,考虑以下场景,我们需要维持一个范围对象Range,其应该满足成员变量lower小于等于upper恒成立,这样才是一个合法的范围。
倘若直接将Range类如下定义,不难发现会有以下问题:如果用户没有按照规则设置lowwer与upper,那么将会导致出现错误的范围
public class Range {
public int lower;
public int upper;
public Range() {
}
}
这样的问题对于无论是sdk或是框架或是产品等是不可接受的,我们不能保证用户一定会合法地使用Range类,不合法的使用有可能对类的安全性乃至系统的安全性造成威胁。
我们可以这样来完善:(重点关注set方法)
public class SafeRange {
private int lower;
private int upper;
public SafeRange(int lower,int upper) {
if (lower > upper) {
try {
throw new Exception("Lower is larger than upper");
} catch (Exception e) {
e.printStackTrace();
}
}
this.lower=lower;
this.upper=upper;
}
public int getLower() {
return lower;
}
public void setLower(int lower) {
if (lower > upper) {
try {
throw new Exception("Lower is larger than upper");
} catch (Exception e) {
e.printStackTrace();
}
}
this.lower = lower;
}
public int getUpper() {
return upper;
}
public void setUpper(int upper) {
if (upper < lower) {
try {
throw new Exception("Upper is larger than lower");
} catch (Exception e) {
e.printStackTrace();
}
}
this.upper = upper;
}
}
在两个set方法中,我们检查了upper和lower的合法性,这样一来在用户使用时,构造出的SafeRange一定满足lower<=upper。
顺带一提,这里的安全性没有涉及到多线程环境下的安全性,如果在多线程环境下,应该再加上synchronize关键字。
2.2、解耦
如果我们是内部人员使用,并且都知晓lower<=upper的规则,在使用Range类时会加上检查语句,那么是不是就可以任然采用原Range类的设计呢?
显然是不能的,考虑以下情况:
某一天,Range类的约束变为了lower<upper(少了等号),那么如果采用原来Range类的设计,我们需要在所有使用到它的地方改变检查语句!这显然是不可行的,会带来巨大的工作量并且不难以确保所有使用到的地方都被修改。
而倘若使用SafeRange类,我们只需要在其set()方法上稍作修改即可。
显然,set()方法在这里提供了解耦的效果
标签:upper,lower,set,get,int,public,Range,安全性 From: https://www.cnblogs.com/sxhxh/p/17373208.html