对基本数据类型的赋值是很简单的。基本类型存储了实际的数值,而并非指向一个对象的引用,所以在为其赋值的时候,是直接将一个地方的内容复制到另一个地方。例如对基本数据类型使用
a=b,那么
b的内容就复制给
a。若接着修改了
a,而
b根本不会受到这种修改的影响。作为程序员,这正是大多数情况下我们所期望的。
程序运行结果如下:
但是在为对象“赋值”的时候,情况却发生了变化。对一个对象进行操作时,我们真正操作的是对对象的引用。所以倘若“将一个对象赋值给另一个对象”,实际是将“引用”从一个地方复制到另一个地方。这意味着假若对对象使用c=d,那么c和d都指向原本只有d指向的那个对象。下面这个例子将向大家阐释这一点。
package assignment;
class Tank {
int level;
}
public class Assignment {
/**
* @param args
*/
public static void main(String[] args) {
Tank t1 = new Tank();
Tank t2 = new Tank();
t1.level = 9;
t2.level = 47;
System.out.println("1: t1.level:" + t1.level + ",t2.level:" + t2.level);
t1 = t2;
System.out.println("2: t1.level:" + t1.level + ",t2.level:" + t2.level);
t1.level = 27;
System.out.println("3: t1.level:" + t1.level + ",t2.level:" + t2.level);
}
}
程序运行结果如下:
1: t1.level:9,t2.level:47
2: t1.level:47,t2.level:47
3: t1.level:27,t2.level:27
Tank类非常简单,它的两个实例(
t1和
t2)是在
main()里创建的。对每个
Tank类对象的
level域都赋予了一个不同的值,然后,将
t2赋给
t1,接着又修改了
t1。在许多编程语言中我们可能会期望
t1和
t2总是相互独立的。但由于赋值操作的是一个对象的引用,所以修改t1的同时也改变了
t2!这是由于
t1和
t2包含相同的引用,它们指向相同的对象。(原本t1包含的对对象的引用,是指向一个值为
9的对象。在对t1赋值的时候,这个引用被覆盖,也就是丢失了,而那个不再被引用的对象会由“垃圾回收器”自动清理。)
这种特殊的现象通常称作“别名现象”,是Java操作对象的一种基本方式。在这个例子中,如果想避免别名问题应该怎么办呢?可以这样写:
t1.level=t2.level;
这样便可以保持两个对象彼此独立,而不是将t1和t2绑定到相同的对象。但你很快就会意识到,直接操作对象的域容易导致混乱,并且,违背了良好的面向对象程序设计的原则。这可不是一个小问题,所以从现在开始大家就应该留意,为对象赋值可能会产生意想不到的结果。