成员属性绝对不能公有的.为什么呢?如果此属性是非final,或者执行可变对象的final引用,一旦使属性公开,就等于放弃了对存储在这个属性中数据进行限制的能力,放弃了强制此属性不可变的能力;当属性被修改时,失去了对它采取任何行动的能力.
因此包含共有可变属性的类不是线程安全的,即使属性是final的,并且引用不可变对象.当属性变成公有,就放弃了切换到”一种新的内部数据表示法”的灵活性.
(个人理解成员属性不可公开,只有进行设置为私有,那么可以对赋值和取值方法进行限制,才能最大限度保持数据的安全性和有效性!)
静态属性也绝对不能公有的!例外情况是常量,通过共有的静态final属性来暴露常量.非常重要的一点,要么常量包含基本数据值,要么常量指向不可变对象的引用.如果final属性包含可变对象的引用,那就具有非fianl属性的缺点.引用不会改变,但引用的对象却可以改变,会导致灾难性的后果.
长度非0的数组总是可变的,所以,类具有共有的静态final数组,或者返回这种属性的访问方法,这几乎总是错误的!为什么呢?因为只要获取引用地址,那么引用的内容可以随便修改.
public static final Thing[]VALUES = {…};
那么如何解决这个问题呢?
1.使共有数组变成私有,并增加一个公有的不可变列表.
private static final Thing[] PRIVATE_VALUES = {…};
public static final List<Thing> VALUES
= Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
2.使数组私有,添加公有访问方法,返回值是私有数组的数据克隆.
private static finalThing[] PRIVATE_VALUES = {…};
public static final Thing[ ]values(){
return PRIVATE_VALUES.clone();
}
两种方法如何选择呢?考虑客户端如何处理结果,哪种返回类型方便,哪种会有更好的性能.
你应该尽可能降低可访问性.仔细设计最小的公有API,应该防止把任何散乱的类,接口,和成员变成API的一部分.除了常量特殊情况外,公有类不应该包含共有属性.确保共有静态属性引用的对象都是不可变的.
{你如何使用上面的知识呢?
1.类的属性和方法最小范围被访问
2.只要获取引用类型属性,那么其数据基本都可以被修改!}