日期:2014-05-20  浏览次数:20687 次

可变对象与不可变对象?
在core java中看到这样一道例题,如下:
Java code

class Test{
  public Date getHireDay(){
       return hireDay;
  }
  private Date hireDay;
}


书中提到:不要编写返回引用可变对象的访问器方法
应更改为如下:
Java code

class Test{
  public Date getHireDay(){
       return (Date)hireDay.clone();
  }
  private Date hireDay;
}


我想问的是,什么是可变对象?
不可变对象是指final类的实例,如String ,Integer这些。
可变对象是是那些没有使用final修饰的类的实例.
不知我这么理解是否正确?
如果不是,那么我们将进行程序设计时该如何判断该对象是否为可变对象或不可变对象?

------解决方案--------------------
我感觉,也不能千篇一律,上面说的情况可能是为了防止其它程序改变对象的属性,(当某一程序在应用此对象时)
Test t=new Test();
Date d=t.getHireDay()//假如期望得到的是2008-06-16
// other...
setXXX(t)//在此方法里调用了t.setHireDay方法,改变了其值,那么上面的d就出现我们不想要的结果,
如果我们返回的是hireDay的一个克隆,那么就不会出现值被改的情况了,因为这个克隆的对象没有引用(句柄)无法对他进行修改。
但是我们有时想用setXXX(t)去改变我们的hireDay,而且这也是我们所期望的,那么我们就不能用clone。所以说因事而定。
------解决方案--------------------
不可变对象没有一个严格明确的定义,如果对象创建出来后(通过构造方法)无论如何对此对象进行非暴力操作(不用反射),此对象的状态(实例域的值)都不会发生变化,那么此对象就是不可变的,相应类就是不可变类,跟是否用 final 修饰没关系,final 修饰类是防止此类被继承。要注意,有些对像创建出来后,即便我们不对它进行任何操作(通过调用方法或访问实例域),它的状态也可能发生变化。
------解决方案--------------------
不知道你理解值传递和引用传递了没有
因为除了基础对象 String,int,boolea,double,float,shot,char,byte....
是使用值传递的
就是说,这些对象在另外一个方法中被调用时,不会改变他们本身的值,改变的只是他们引用的一个副本

但是,其他所有的实例对象都是使用引用传递的
当你把一个对象通过一个GET方法传递出去以后,在外部可以通过这个引用对象上的方法来改变他对象中属性的值

举个例子
Java code

public class myint{
 public int i = 0;
}
public class test {
 int i = 0;
 myint Obj_i = new myint();

 public int getI(){ return i;}
 public myint getMyInt(){ return Obj_i;}
}
public class test2 {
 public static void main(String[] args) {
  test t = new test();
  int i = t.getI();
  myint Obj_i = t.getMyInt();

 // 尝试改变i 和obj_i的值
  i = 10;
  Obj_i.i = 20;

 //显示test上原本的属性
  System.out.println(t.i);   // 输出仍然是0  test上的i并没有被改变
  System.out.println(t.getMyInt().i);   // 输出是20  test上的Obj_i.i的值被改变了
 }
}