贴段代码来看封装中的问题:class Employee{
  ...
  private Date birthday;
  ...  public Date getBirthday()
  {
    return birthday;
  }
  ...
}Employee emp = new Employee();
Date d = emp.getBirthday();
d.setYear(2005);  //修改了私有域容易犯的错误啊!

解决方案 »

  1.   

    ft,当然不是说那个了,贴段代码吧
    import java.lang.reflect.*;
    import java.util.*;
    public class ObjectAnalyzerTest
    {
      public static void main(String[] args)
       {  Employee harry  = new Employee("Harry Hacker", 35000,
             1996,12, 1);
          System.out.println(harry);
          System.out.println(harry);
       }
    }
    class ObjectAnalyzer
    {
       public static String toString(Object obj)
       {
          Class cl = obj.getClass();
          String r = cl.getName();
          do {
            r+="[";
            Field[] fields=cl.getDeclaredFields();
          AccessibleObject.setAccessible(fields, true);
          for (int i = 0; i < fields.length; i++)
          {
             Field f = fields[i];
             r += f.getName() +"(";
             r+=f.getType().toString()+")=";
             try
             {
                Object val = f.get(obj);
                if(val instanceof String)
                  f.set(obj,"newname");
                r += val.toString();
             } catch (IllegalAccessException e)
             {  r += "???";
             }
             if (i < fields.length - 1)
                r += ",";
          }
          r+="]";
          cl=cl.getSuperclass();
       }
       while(cl!=Object.class);
       return r;
     }
    }class Employee
    {
       public Employee(String n, double s, int year, int month,int day)
       {  name = n;
          salary = s;
          GregorianCalendar calander=new GregorianCalendar(year,month-1,day);
          hireDay = calander.getTime();
       }
       public String toString()
       {  return ObjectAnalyzer.toString(this);
       }
       private String name;
       private double salary;
       private Date hireDay;
    }
      

  2.   

    为了说明问题,我把Empolyee所有getter,setter函数全部去掉,只保留tostring函数用来被main中的println调用,而toString()实际上由另外一个类ObjectAnalyzer完成,可是这个类却能够访问到employee中的私有成员变量,并且更能直接改变它的值(把name改成了"newname"),我想这足够证明我的看法了吧
      

  3.   

    同意楼主的意见, 其实我认为像JAVA这样的语言,肯定在提供访问某些违反封装性的手段,其目的如楼主据说,反射机制中很多地方都是这样的,只要我们自己开发应用程序时注意避免就行了.
      

  4.   

    尽量不要破坏封装,任何事情不要说绝对。
    三楼的朋友用Object.Clone;
      

  5.   

    封装应该是一种思路、思想
    却不是强制的手段
    毕竟java虚拟机需要通过某些手段去获悉类的内部结构和实现