使可变性最小化(15)

1、java语言支持四种类型:

(1)接口(interface):

(2)类(class):

(3)数组(Array):

(4)基本类型(primitive):唯一非引用类型(reference type)

2、方法签名:包括方法名称、参数,不包括返回值;

《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《

3、不可变类

  • 实例不可被修改类
  • 每个实例中包含的所有信息,必须在创建的时候提供,并在整个生命周期不可变
  • 例如:String、基本类型包装类、BigInteger、BigDecimal
  • 比可变类,易于设计使用,不易出错、更加安全

4、成为不可变类,五条规则

(1)不提供任何修改对象状态的方法

(2)保证类不会被扩展

  • 这样可以防止粗心、恶意子类,假装对象状态已经改变;
  • 防子类化,一般使用 final 类

(3)所有的类都是 final 

  • 通过系统的强制,表明意图

(3.1)不可变类变成 final 的另一种做法:

  • 使不可变类所有构造方法都变成私有或包级私有,添加公有静态工厂,替换公有构造器

(4)所有域都私有

  • 技术上允许不可变类具有公有 final 域(域包含基本类型值或 不可变对象引用)
  • 不建议上述做法原因:以后版本无法改变内部表示法

(5)确保对任何可变组件的互斥访问

  • 如果类具有可变对象的域,须保证客户端无法或者这些对象的引用
  • 不要用客户端提供的对象引用初始化 可变对象的域
  • 不要从任何访问方法返回该对象引用
  • 在构造器、访问方法、readObject方法(76条)中,请使用保护性拷贝(39条)

5、函数方式的模式

  • 对操作数进行运算,但不修改,返回新创建的实例
  • 大多数不可变类都是用该模式
  • 该做法带来了不可变性
  • 约束关系在整个生命周期都不变,不需要额外代码维护约束关系

163523_9miK_3847203.png

6、不可变对象本质上是线程安全的,且不要求线程同步

  • 多线程并发访问不可变类对象,不会破坏对象,线程安全最容易实现
  • 不可变对象可以被自由的共享
  • 鼓励客户端尽可能重用现有实例(简单实现:频繁用到的值,提供公有静态 final 常量)
  • 对不可变类提供静态工厂<1条>,缓存公用频繁使用的实例
  • 基本类型包装类、BigDecimal等就有这样静态工厂
  • 使用静态工厂而不是公有构造器,以后添加缓存更灵活

7、不可变对象可以被自由的共享

  • 永远不需要进行保护性拷贝<39条>
  • 不应该对不可变类提供 clone 方法或 拷贝构造器<11条>
  • String类有拷贝构造器,尽量不要使用<5条>

8、不仅可以共享不可变对象,可以共享内部信息

  • 不可变类BigInteger,在使用negate()获得相反数时,内部mag指向原有对象的mag数组
  • 因为是不可变类,对象不会被修改才可以这么操作

9、不可变对象真正缺点

  • 对于每一个单独的值都需要一个单独的对象;
  • 比如:一个百万位的BigInteger,运算时需要不停创建新对象,性能消耗巨大;
  • BitSet 则允许固定时间内,改变某一位

10、如果不可预测,提供公有可变嵌套

  • String类的可变公有嵌套:StringBuild(和已经基本废止的StringBuffer)

11、如果可预测,可以采用内部可变对象,存取中间值

  • 这样,不用每一步都创建不可变对象

12、BigInteger和BigDecimal刚北边写出来时,不可变类必须是 final 未得到广泛认同

  • 这俩类,存在被继承和被篡改的风险

13、不可变类没有方法会修改对象,所有域必须是 final

  • 为提高性能可以有非 final 的域:第一次运算时将开销昂贵的结果保存起来,下次直接用
  • 不可变性,保证了结果的正确性

14、序列化功能一条告诫:

  • 不可变类实现了Serializable接口,需要显式readObject等4个方法
  • 攻击者可能从不可变类创建可变对象<76条>

15、没有好的理由,类就要做成不可变得

16、类不能做成不可变的,也要尽量限制其可变性;

17、除非有好的理由,每个域都应该是 final 的

18、构造器和静态工厂外,不应再提供公有初始化方法

19、不可变类不要提供重新初始化方法

转载于:https://my.oschina.net/u/3847203/blog/1816279

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值