转自https://blog.csdn.net/ksjay_1943/article/details/53353359
String、Long、Double是不可变类
1)类声明为final,不可以被继承
2)所有成员是私有的,不允许直接被访问
3)对变量不要setter方法
4)所有可变的变量是final的,只能赋值一次
5)通过构造器初始化所有成员,进行深拷贝
6)在getter方法中不能返回对象本身,返回对象的拷贝
package FinalClassDemo;
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= (String) 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 Shallow Copy for Object initialization
true
false
ce id:10
ce name:original
ce testMap:{1=first, 2=second}
ce id after local variable change:10
ce name after local variable change:original
ce testMap after local variable change:{1=first, 2=second, 3=third}
ce testMap after changing variable from accessor methods:{1=first, 2=second, 3=third}
//深拷贝测试结果:
Performing Deep Copy for Object initialization
true
false
ce id:10
ce name:original
ce testMap:{1=first, 2=second}
ce id after local variable change:10
ce name after local variable change:original
ce testMap after local variable change:{1=first, 2=second}
ce testMap after changing variable from accessor methods:{1=first, 2=second}
1)不可变类只有getter方法
2)不可变类只有一个私有的构造器,以Builder对象作为参数来创建不可变对象
3)如果成员是可变的(如HAshMap),需要使用深拷贝或克隆来防止成员变量被改变
4)使用建造者模式创建不可变类
使用建造者模式来创建不可变类:
package FinalClassDemo;
import java.util.HashMap;
public class ImmutableClass {
//required fields
private int id;
private String name;
//optional fields
private HashMap properties;
private String company;
public int getId() {
return id;
}
public String getName() {
return name;
}
public HashMap getProperties() {
//return cloned object to avoid changing it by the client application
return (HashMap) properties.clone();
}
public String getCompany() {
return company;
}
private ImmutableClass(ImmutableClassBuilder builder) {
this.id = builder.id;
this.name = builder.name;
this.properties = builder.properties;
this.company = builder.company;
}
//Builder class
public static class ImmutableClassBuilder{
//required fields
private int id;
private String name;
//optional fields
private HashMap properties;
private String company;
public ImmutableClassBuilder(int i, String nm){
this.id=i;
this.name=nm;
}
public ImmutableClassBuilder setProperties(HashMap hm){
this.properties = (HashMap) hm.clone();
return this;
}
public ImmutableClassBuilder setCompany(String comp){
this.company = comp;
return this;
}
public ImmutableClass build(){
return new ImmutableClass(this);
}
}
}
测试以上:
package FinalClassDemo;
import java.util.HashMap;
public class ImmutableBuilderTest {
public static void main(String[] args) {
// Getting immutable class only with required parameters
ImmutableClass immutableClass = new ImmutableClass.ImmutableClassBuilder(1, "Pankaj").build();
HashMap hm = new HashMap();
hm.put("Name", "Pankaj");
hm.put("City", "San Jose");
// Getting immutable class with optional parameters
ImmutableClass immutableClass1 = new ImmutableClass.ImmutableClassBuilder(1, "Pankaj")
.setCompany("Apple").setProperties(hm).build();
//Testing immutability
HashMap hm1 = immutableClass1.getProperties();
//lets modify the Object passed as argument or get from the Object
hm1.put("test", "test");
//check that immutable class properties are not changed
System.out.println(immutableClass1.getProperties());
}
}
//输出结果:创建不可变类成功
{City=San Jose, Name=Pankaj}