不可变类顾名思义就是这个类被实例化之后不可被重新赋值,java提供的八个包装类和java.lang.String都是不可变类。
创建自定义不可变类需要遵守的规则:
1、使用private和final修饰成员变量。
2、提供带参构造方法,用于初始化成员变量。
3、不要为成员变量提供setter方法。
4、如果成员变量中有可变类时需要重写Object中的hashCode方法和equals方法。
例如创建一个不可变的Person类
public classPerson {private finalString Name;private finalString gender;/** 无参构造方法*/
publicPerson(){this.Name="";this.gender="";
}/** 有参构造方法*/
publicPerson(String Name , String gender){this.Name =Name;this.gender =gender;
}publicString getName() {returnName;
}publicString getGender() {returngender;
}/** 重写hashCode方法
* (non-Javadoc)
* @see java.lang.Object#hashCode()*/@Overridepublic inthashCode() {return Name.hashCode() +gender.hashCode();
}/** 重写equals方法
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)*/@Overridepublic booleanequals(Object obj) {if(this ==obj)return true;if(obj != null && obj.getClass() == this.getClass()){
Person pe=(Person)obj;if(this.getName().equals(pe.getName()) && this.getGender().equals(pe.getGender()))return true;
}return false;
}
以上这个Person类中成员变量都是不可变类,如果其中有可变类,那么用以上的方法创建不可变类是有问题的,虽然Person的属性是不可变的,但属性引用的对象是可变的,
这样就会使Person的不可变性遭到破坏,例如如下例子
先创建一个可变类College
public classCollege {privateString collNo;privateString collName;publicCollege(String collNo, String collName) {super();this.collNo =collNo;this.collName =collName;
}publicCollege() {super();
}publicString getCollNo() {returncollNo;
}public voidsetCollNo(String collNo) {this.collNo =collNo;
}publicString getCollName() {returncollName;
}public voidsetCollName(String collName) {this.collName =collName;
}
@OverridepublicString toString() {return "College [collNo=" + collNo + ", collName=" + collName + "]";
}
在Person中引用College
public classPerson {private finalCollege college;publicPerson() {this.college = null;
}publicPerson(College college) {super();this.college =college;
}publicCollege getCollege() {returncollege;
}
@OverridepublicString toString() {return "Person [college=" + college + "]";
}public static voidmain(String[] args){
College coll= new College("123456","土木工程");
Person pe= newPerson(coll);
System.out.println("----->" +pe);
coll.setCollName("信息工程"); //这样就会改变Person对象
System.out.println("======>" +pe);
}
那么怎样才能创建有可变属性的不可变类呢?我们只要让程序无法访问到College属性即可
public classPerson {private finalCollege college;publicPerson() {this.college = null;
}publicPerson(College college) {//创建一个和传入对象有相同属性的College,赋值给成员变量
this.college = newCollege(college.getCollNo(),college.getCollName());
}publicCollege getCollege() {//创建一个College将属性的值赋值给它并返回
return new College(this.college.getCollNo(),this.college.getCollNo());
}
@OverridepublicString toString() {return "Person [college=" + college + "]";
}
以上思路就是分离外界和Person类中可变属性的联系,是的程序不能直接作用于属性,这样就创建了含可变类属性的不可变类