- //不可变类
- package bin;
- class Name
- {
- private String firstName;
- private String lastName;
- public Name(){}
- public Name(String firstName,String lastName)
- {
- this.firstName = firstName;
- this.lastName = lastName;
- }
- public void setFirstName(String firstName)
- {
- this.firstName = firstName;
- }
- public String getFirstName()
- {
- return firstName;
- }
- public void setLastName(String lastName)
- {
- this.lastName = lastName;
- }
- public String getLastName()
- {
- return lastName;
- }
- }
- //定义Person不可变类
- public class Person
- {
- private final Name name;
- /*
- 原来的代码
- public Person(Name name)
- {
- this.name = name;
- }
- public Name getName()
- {
- return 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);
- System.out.println(p.getName().getFirstName());
- n.setFirstName("八戒");
- System.out.println(p.getName().getFirstName());
- }
- /*
- 原来是程序中Person对象的Name属性的firstName属性改变,就导致Person的改变
- 原来输出结果为:悟空,八戒。破坏了Person类的设计初衷。
- 为了保持Person对象的不可变,必须保护好Person对象的引用类型属性:name,让程序
- 无法访问到Person对象的name属性,也就无法利用name属性的可变性来改变Person对象了
- 更改后:当程序向Person构造器里传入一个Name对象时,该构造器创建Person对象时并不是
- 直接利用已有的Name对象(利用已有的Name对象有风险,因为这个Name对象的可变的,如果
- 改变这个Name对象,Person也将改变),而是重新创建了一个Name对象来赋给Person对象的
- name属性。当Person对象返回name属性时,不没有直接把name属性返回,直接返回name属性
- 也可能导致该name属性所引用的Name对象被修改。
- 修改后结果:悟空 悟空
- */
- }