Effective Java-Item15

第15条 使可变性最小化

      相对于可变对象,不可变对象只拥有一个状态(即初始化对象时的状态),这样的对象更好理解,在出现bug时也容易调试,因为它自始至终都没有变化。在并发环境下,不可变对象不需要线程同步(这就是为什么Erlang——这个为并发而生的语言——中的变量只能被赋值一次),它们是线程安全的,可以被自由的共享。

      不可变类的缺点就是每个值都需要一个单独的对象,所以就要尽量重用这些对象,保证每个值只有一个对象。对于经常使用的值,可以作为类的静态final域。还可以通过静态工厂方法来缓存对象,以达到重用的目的。

      在不可变对象上进行多步骤的操作,且每个步骤都会产生一个对象,这会产生大量的垃圾对象,影响性能。这种情况有两种方法,一是在运算步骤中使用基本数据类型,防止产生垃圾对象;二是提供一个对应功能的可变类。

      值类    ----> 不可变类

      实体类 ----> 可变类

      对于值类,像基本数据类型的包装类,String等这样表示一个值的类,可以将其设置为不可变的。这些类通常看作是基本数据类型,用于构建其他类。而实体类,它的状态会发生变化,像银行系统中的账户类(Account)需要有一个double类型的值表示账户余额,并有其它方法来改变它。对于可变类,也应该做到只有当一个域不得不变化时,才将它设置为可变的,否则就必须是不可变的。即对于不能做成不可变的类,仍然应该尽可能地限制它的可变性,这样可以降低对象存在的状态数,更容易地分析对象的行为,同时减低出错的可能性。

      要使一个类不可变,必须满足5个条件:

      1.没有任何修改对象状态的方法

      2.保证类不会被扩展。有两种方法,一是使这个类成为final的;二是使所有的构造器都是private的,并提供静态工厂方法获得对象

      3.使所有域都是final的

      4.使所有域都是private的。对于静态常量或者指向不可变对象的final引用,可以通过域访问,但是这失去了改变内部表示法的灵活性(通过访问方法获得)。

      5.确保对于任何可变组件的互斥访问。如果类具有指向可变对象的域,必须保证客户类不能获得这些引用,并且不能用客户端提供的类来初始化这些域(因为客户端也会持有指向该对象的引用,可以改变其状态)。不能直接在访问方法中返回这些对象引用,应该使用保护性拷贝技术。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值