您的位置:首页 > 编程语言 > Java开发

51 Java final——不可变类

2014-02-09 08:04 246 查看
/**
* 不可变类
* ——创建该类的实例后,该实例的Field是不可改变的
* @author Administrator
*
*/
//下面测试java.lang.String 类的equals和hashCode方法
public class ImmutableClass {

public static void main(String[] args) {
String str1=new String("Hello");
String str2=new String("Hello");

System.out.println(str1==str2);//false
System.out.println(str1.equals(str2));//true
System.out.println(str1.hashCode());
//下面两次输出的hashcode相同
System.out.println(str2.hashCode());

}
}


/*
* 下面定义不可变类的Address类,程序把address类的
* detail和postCode成员变量都是用private隐藏起来
* 并使用final 修饰这两个成员变量,不准许其他抵港修改这两个Field值
*/
public class Address {

private final String detail;
private final String postCode;
//在构造器中初始化两个实例Field
public Address(){
this.detail="";
this.postCode="";
}
public Address(String detail,String postCode){
this.detail=detail;
this.postCode=postCode;
}

//仅为来年哥哥实例Field提供getter方法
public String getDetail() {
return detail;
}
public String getPostCode() {
return postCode;
}
//重写equals 方法,判断两个对象是否相等
public boolean equals(Object obj) {
if(this==obj){
return true;
}
if(obj != null && obj.getClass()==Address.class){
Address ad=(Address)obj;
//当detail 和 postCode相等时,可以认为两个Address对象相等
if(this.getDetail().equals(ad.getDetail())&&this.getPostCode().equals(ad.getPostCode())){
return true;
}
}
return false;

}
public int hashCode(){
return detail.hashCode()+postCode.hashCode()*31;

}
public static void main(String[] args) {
// TODO Auto-generated method stub
Address ad1=new Address("abc","td");
Address ad2=new Address("abc","td");

System.out.println(ad1.equals(ad2));//true

}

}


实例:

/*
* 当final修饰引用类型变量时,仅表示这个引用类型变量不可被重新复制,当引用类型
* 变量所指向的对象依然可改变,这就产生一个问题,当创建不可变类时,如果它包含Field
* 的类型是可变的,那么其对象的Field值依然是可改变的——这个不可变类其实是失败的
*/
//下面程序师徒定义一个不可变的Person类,但因为Person类包含一个引用类型Field,
//且这个引用类是可变类,所以导致Person类也变成了可变类
class Name {
private String firstName;
private String lastName;

public Name() {
}

public Name(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

}

public class Person {

private final Name name;

public Person(Name name) {
this.name = name;
}

public Name getName() {
return name;
}

/**
* 运行程序,Person对象的name的fristName已经被改变了
* @param args
*/
public static void main(String[] args) {
Name n = new Name("悟空", "孙");
Person p = new Person(n);
// Person 对象的name的firstName值为“悟空”
System.out.println(p.getName().getFirstName());//悟空
n.setFirstName("八戒");
// Person 对象的name的firstName值被改为“八戒”
System.out.println(p.getName().getFirstName());//八戒
}

}


/*
* 为保持Person对象的不可变性,必须保护好Person对象的应用类型Field:name
* 让程序无法访问Person对象的name Field,也就无法利用name Field的可变
* 性来改变Person对象了
*/
public class Person{
private final Name name;
public Person(Name name)
{
this.name=new Name(name.getFirstName(), name.getLastName());
}

public Name getName()
{
return new Name(name.getFirstName(),name.getLastName());

}

public static void main(String[] args) {
Name n = new Name("悟空", "孙");
Person p = new Person(n);
// Person 对象的name的firstName值为“悟空”
System.out.println(p.getName().getFirstName());//悟空
n.setFirstName("八戒");
// Person 对象的name的firstName值被改为“八戒”
System.out.println(p.getName().getFirstName());//悟空
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: