关于java中的不可变类(转)
如何在Java中写出Immutable的类?
要写出这样的类,需要遵循以下几个原则:
1)immutable对象的状态在创建之后就不能发生改变,任何对它的改变都应该产生一个新的对象。
2)Immutable类的所有的属性都应该是final的。
3)对象必须被正确的创建,比如:对象引用在对象创建过程中不能泄露(leak)。
4)对象应该是final的,以此来限制子类继承父类,以避免子类改变了父类的immutable特性。
5)如果类中包含mutable类对象,那么返回给客户端的时候,返回该对象的一个拷贝,而不是该对象本身(该条可以归为第一条中的一个特例)
当然不完全遵守上面的原则也能够创建immutable的类,比如String的hashcode就不是final的,但它能保证每次调用它的值都是一致的,无论你多少次计算这个值,它都是一致的,因为这些值的是通过计算final的属性得来的!
下面是一个例子:
public final class Contacts {private final String name;private final String mobile;public Contacts(String name, String mobile) {this.name = name;this.mobile = mobile;}public String getName(){return name;}public String getMobile(){return mobile;} }
我们为类添加了final修饰,从而避免因为继承和多态引起的immutable风险。
上面是最简单的一种实现immutable类的方式,可以看到它的所有属性都是final的。
有时候你要实现的immutable类中可能包含mutable的类,比如java.util.Date,尽管你将其设置成了final的,但是它的值还是可以被修改的,为了避免这个问题,我们建议返回给用户该对象的一个拷贝,这也是Java的最佳实践之一。下面是一个创建包含mutable类对象的immutable类的例子:
public final class ImmutableReminder{private final Date remindingDate;public ImmutableReminder (Date remindingDate) {if(remindingDate.getTime() < System.currentTimeMillis()){throw new IllegalArgumentException("Can not set reminder” +“ for past time: " + remindingDate); }this.remindingDate = new Date(remindingDate.getTime());}public Date getRemindingDate() {return (Date) remindingDate.clone();} }
上面的getRemindingDate()方法可以看到,返回给用户的是类中的remindingDate属性的一个拷贝,这样的话如果别人通过getRemindingDate()方法获得了一个Date对象,然后修改了这个Date对象的值,那么这个值的修改将不会导致ImmutableReminder类对象中remindingDate值的修改。
使用Immutable类的好处:
1)Immutable对象是线程安全的,可以不用被synchronize就在并发环境中共享
2)Immutable对象简化了程序开发,因为它无需使用额外的锁机制就可以在线程间共享
3)Immutable对象提高了程序的性能,因为它减少了synchroinzed的使用
4)Immutable对象是可以被重复使用的,你可以将它们缓存起来重复使用,就像字符串字面量和整型数字一样。你可以使用静态工厂方法来提供类似于valueOf()这样的方法,它可以从缓存中返回一个已经存在的Immutable对象,而不是重新创建一个。
immutable也有一个缺点就是会制造大量垃圾,由于他们不能被重用而且对于它们的使用就是”用“然后”扔“,字符串就是一个典型的例子,它会创造很多的垃圾,给垃圾收集带来很大的麻烦。当然这只是个极端的例子,合理的使用immutable对象会创造很大的价值。
转载于:https://www.cnblogs.com/gdjdsjh/p/5111083.html
关于java中的不可变类(转)相关推荐
- setyear java_如何在Java中创建不可变类
如果对象在构造后无法更改,则该对象是不可变的.不可变对象不会以任何方式暴露其他对象来修改其状态; 对象的字段仅在构造函数内初始化一次,并且永远不会再次更改. 在本文中,我们将定义在Java中创建不可变 ...
- java创建一个不可变对象_如何在Java中创建不可变类?
java创建一个不可变对象 Today we will learn about the immutable class in Java. What are immutable classes? The ...
- Java中的不可变类
随时随地技术实战干货,获取项目源码.学习资料,请关注源代码社区公众号(ydmsq666) 概念:不可变类的意思是创建该类的实例后,该实例的属性是不可改变的.java中的8个包装类和String类都是不 ...
- JAVA中常量使用常量类或者常量接口还是使用枚举,错误代码和中文可变信息的枚举实现
文章目录 关于"JAVA中常量使用常量类或者常量接口还是使用枚举",已有定论-使用枚举,原因就不再展开了. 借助java枚举,可以在定义错误名称和代码的同时,定义中文描述信息,但是 ...
- 深入理解Java中的不可变对象
二哥,你能给我说说为什么 String 是 immutable 类(不可变对象)吗?我想研究它,想知道为什么它就不可变了,这种强烈的愿望就像想研究浩瀚的星空一样.但无奈自身功力有限,始终觉得雾里看花终 ...
- Java中通过代理对类进行修改
JAVA中的静态代理.动态代理及JDK proxy和CGLIB.Javassist.ASM实践 简介 Java中对已经有的类进行修改,改变或调整其执行,这可以通过代理来实现.Java的class文件是 ...
- java中的starts_Java Math类静态double nextAfter(double starts,double direction)示例
java中的starts 数学类静态double nextAfter(双向启动,双向) (Math Class static double nextAfter(double starts , doub ...
- Java中Date和Calender类的使用方法
查看文章 Java中Date和Calender类的使用方法 2009-10-04 20:49 Date和Calendar是Java类库里提供对时间进行处理的类,由于日期在商业逻辑的应用中占据着 ...
- 《Java并发编程的艺术》——Java中的并发工具类、线程池、Execute框架(笔记)
文章目录 八.Java中的并发工具类 8.1 等待多线程完成的CountDownLatch 8.2 同步屏障CyclicBarrier 8.2.1 CyclicBarrier简介 8.2.2 Cycl ...
最新文章
- iis5.1配置php5.3.1详解,WinXP IIS 5.1 PHP 5.3 VC9.0 配置详解
- Javascript的数据结构与算法(一)
- python 如何把小数变成百分数格式
- 如何下载和安装SQL Server数据库实验助手(DEA v2.0)
- java 找出调用的方法_如何找到用Java调用给定方法的所有方法?
- Ubuntu18.04取消VIM自动备份文件
- 魔兽世界服务器修改模型,修改模型教程!
- C++ 小游戏 视频及资料集(9)
- kaptcha生成自定义图片验证码
- 在wamp 或者xamp 下测试多个独立的网页文件
- 【软件测试】——软件测试经验总结
- 【DBC专题】-4-DBC文件中的Signal信号字节顺序Motorola和Intel介绍
- 哪款蓝牙耳机耳朵不疼?久戴不疼的骨传导耳机
- h标签本身自带间距 去除方法
- 【数据库】数据库基本知识
- 2020-01-08 Oracle 数据库储存生僻字
- 360年会三娘逆袭 女程序员戴假发化妆成-搜狐滚动
- InDesign插件--常规功能开发--版面调整--js脚本开发--ID插件
- 面试-Senior Specialist for Devops-车企
- Spring IoC的理解----找女朋友的方法
热门文章
- Vivado HLS error: Cannot find ISE in the PATH variable or it's an unsupported version
- SQLite主键自增需要设置为integer PRIMARY KEY
- ubuntu11.04中如何像其他版本一样快速回到桌面
- poj 2891 Strange Way to Express Integers 2012-09-05
- 盘点机器学习和统计模型的差异
- JavaScript 同源策略
- Silverlight与WPF中BeginInvoke的差异
- Silverlight 参考:三维效果(透视转换) -- MSN
- 转载:浅谈软件测试流程
- soap 版本可能不匹配: 出现意外的 envelope 命名空间_Collaboratorv11.5版本上新!GitHub Polling集成被弃用!...