51 Java final——不可变类

/**
 * 不可变类 
 * ——创建该类的实例后,该实例的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());//悟空
	}

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值