java有一个非常重要的安全特性叫封装。
但是有时候编程不注意,直接将一个对象的引用返回,就破坏了封装性,也增加了程序出错的可能,例如下面这段代码。
package com.amber.ivy;
import java.text.SimpleDateFormat;
import java.util.Calendar;
/**
* 返回引用可能破坏java封装性例子
* @author ivyamber
*
*/
public class CloneDemo
{
public static void main(String[]args)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//初始化一个员工,以后员工的姓名和生日都不许修改
Employee e = new Employee("ivyamber",Calendar.getInstance());
Calendar birthday = e.getBirthday();
System.out.println(sdf.format(birthday.getTime()));
//员工生日被修改了,因为birthday是一个对象引用,破坏了封装性
birthday.add(Calendar.MONTH, -1);
System.out.println(sdf.format(e.getBirthday().getTime()));
}
}
class Employee
{
private String name;
private Calendar birthday;
public Employee(String name,Calendar birthday)
{
this.name = name;
this.birthday = birthday;
}
public String getName() {
return name;
}
public Calendar getBirthday() {
return birthday;
}
}
那么怎么避免呢,就是使用clone类,将返回对象修改为返回对象的拷贝。
修改后
package com.amber.ivy;
import java.text.SimpleDateFormat;
import java.util.Calendar;
/**
* 返回引用可能破坏java封装性例子
* @author ivyamber
*
*/
public class CloneDemo
{
public static void main(String[]args)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//初始化一个员工,以后员工的姓名和生日都不许修改
Employee e = new Employee("ivyamber",Calendar.getInstance());
Calendar birthday = e.getBirthday();
System.out.println("生日:"+sdf.format(birthday.getTime()));
//员工生日被修改了,因为birthday是一个对象引用,破坏了封装性
birthday.add(Calendar.MONTH, -1);
System.out.println("修改后的生日:"+sdf.format(e.getBirthday().getTime()));
}
}
class Employee
{
private String name;
private Calendar birthday;
public Employee(String name,Calendar birthday)
{
this.name = name;
this.birthday = birthday;
}
public String getName() {
return name;
}
public Calendar getBirthday() {
return (Calendar) birthday.clone();//返回对象的拷贝
}
}