Java写一个不可变类(如String)
来源:互联网 发布:七局网络教育 编辑:程序博客网 时间:2024/05/17 03:32
(转载)
本文由 ImportNew - 唐小娟 翻译自 Journaldev。欢迎加入翻译小组。
不可变的对象指的是一旦创建之后,它的状态就不能改变。String类就是个不可变类,它的对象一旦创建之后,值就不能被改变了。
阅读更多: 为什么String类是不可变的
不可变对象对于缓存是非常好的选择,因为你不需要担心它的值会被更改。不可变类的另外一个好处是它自身是线程安全的,你不需要考虑多线程环境下的线程安全问题。
下面是创建不可变类的方法,我也给出了代码,加深理解。
要创建不可变类,要实现下面几个步骤:
将类声明为final,所以它不能被继承
将所有的成员声明为私有的,这样就不允许直接访问这些成员
对变量不要提供setter方法
将所有可变的成员声明为final,这样只能对它们赋值一次
通过构造器初始化所有成员,进行深拷贝(deep copy)
在getter方法中,不要直接返回对象本身,而是克隆对象,并返回对象的拷贝
为了理解第5和第6条,我将使用FinalClassExample来阐明。
FinalClassExample.java
package com.journaldev.java;import java.util.HashMap;import java.util.Iterator;public final class FinalClassExample { private final int id; private final String name; private final HashMap testMap; public int getId() { return id; } public String getName() { return name; } /** * 可变对象的访问方法 */ public HashMap getTestMap() { //return testMap; return (HashMap) testMap.clone(); } /** * 实现深拷贝(deep copy)的构造器 * @param i * @param n * @param hm */ public FinalClassExample(int i, String n, HashMap hm){ System.out.println("Performing Deep Copy for Object initialization"); this.id=i; this.name=n; HashMap tempMap=new HashMap(); String key; Iterator it = hm.keySet().iterator(); while(it.hasNext()){ key=it.next(); tempMap.put(key, hm.get(key)); } this.testMap=tempMap; } /** * 实现浅拷贝(shallow copy)的构造器 * @param i * @param n * @param hm */ /** public FinalClassExample(int i, String n, HashMap hm){ System.out.println("Performing Shallow Copy for Object initialization"); this.id=i; this.name=n; this.testMap=hm; } */ /** * 测试浅拷贝的结果 * 为了创建不可变类,要使用深拷贝 * @param args */ public static void main(String[] args) { HashMap h1 = new HashMap(); h1.put("1", "first"); h1.put("2", "second"); String s = "original"; int i=10; FinalClassExample ce = new FinalClassExample(i,s,h1); //Lets see whether its copy by field or reference System.out.println(s==ce.getName()); System.out.println(h1 == ce.getTestMap()); //print the ce values System.out.println("ce id:"+ce.getId()); System.out.println("ce name:"+ce.getName()); System.out.println("ce testMap:"+ce.getTestMap()); //change the local variable values i=20; s="modified"; h1.put("3", "third"); //print the values again System.out.println("ce id after local variable change:"+ce.getId()); System.out.println("ce name after local variable change:"+ce.getName()); System.out.println("ce testMap after local variable change:"+ce.getTestMap()); HashMap hmTest = ce.getTestMap(); hmTest.put("4", "new"); System.out.println("ce testMap after changing variable from accessor methods:"+ce.getTestMap()); }}
输出:
Performing Deep Copy for Object initialization
true
false
ce id:10
ce name:original
ce testMap:{2=second, 1=first}
ce id after local variable change:10
ce name after local variable change:original
ce testMap after local variable change:{2=second, 1=first}
ce testMap after changing variable from accessor methods:{2=second, 1=first}
现在我们注释掉深拷贝的构造器,取消对浅拷贝构造器的注释。也对getTestMap()方法中的返回语句取消注释,返回实际的对象引用。然后再一次执行代码。
Performing Shallow Copy for Object initialization
true
true
ce id:10
ce name:original
ce testMap:{2=second, 1=first}
ce id after local variable change:10
ce name after local variable change:original
ce testMap after local variable change:{3=third, 2=second, 1=first}
ce testMap after changing variable from accessor methods:{3=third, 2=second, 1=first, 4=new}
从输出可以看出,HashMap的值被更改了,因为构造器实现的是浅拷贝,而且在getter方法中返回的是原本对象的引用。
如果我漏掉了某些细节,请指出。
更多阅读: 如果不可变类有许多成员,而其中一些是可选的,那么我们可以使用建造者模式(builder pattern)来创建不可变类。
原文链接: http://www.journaldev.com/129/how-to-write-an-immutable-class
翻译: ImportNew.com - 唐小娟
译文链接: http://www.importnew.com/7535.html
- Java写一个不可变类(如String)
- Java String不可变
- 如何写一个不可变类?
- 如何写一个不可变类
- 如何写一个不可变类
- 如何写一个不可变类?
- 如何写一个不可变类?
- 如何写一个不可变类?
- Java String不可变类总结
- string 不可变类
- Java中的String类(不可变类)变还是不变?
- JAVA String 不可变对象
- JAVA String类型不可变
- String为不可变类
- 不可变的String类
- Java 不可变类
- Java不可变类
- java 不可变类
- 集合
- tensorflow安装测试运行常见问题
- OSG+VS2010+win7 环境搭建教程
- 作业python 内部小卖铺
- 湖南省第九届大学生计算机程序设计竞赛 G
- Java写一个不可变类(如String)
- yolo2-vs2015-CUDA8.0-OPENCV3.2_DEMO
- “玲珑杯”ACM比赛 Round #18 C(dp)
- 第三方登录
- [leetcode]633. Sum of Square Numbers
- 为什么要将基类的析构函数声明为虚函数
- xml/schema/wsdl
- MeshLab配置和编译
- JS窗体弹出问题输入答案_prompt