炸一看,觉得赋值操作没什么可说的,无非就是:使用操作符“=”,表示 “把右边的值复制给左边”,右边的值可以是任何常数、变量或者表达式(只要它能生成一个值就行)
但是在JAVA中,赋值的操作并不紧紧表示值的复制,单纯的这样认为,会掉入赋 值操作的陷阱,值得注意!
一、值复制
对基本数据类型的赋值是值的复制。基本类型存储了实际的数值,而不是指向一个对象的引用,所以在为其赋值的时候,是直接将内容复制给左边的变量;例如,对 基本数据类型使用a = b,就是将b的值复制给a,如果接着又修改了a,而b的值不会受这个修改的影响。这是大多数情况下我们所期望的。
二、引用复制
但在对对象“赋值”的时候,情况却发生变化,对对象赋值实际上是对对象的引用的复制;对一个对象进行操作时,我们真正操作的是对对象的引用。所以如果“将 一个对象赋值给另一个对象”,实际是将对象的“引用”复制到另一个对象,如果赋值后其中一个对象的属性发生变化,那么另外那个对象也会受到这种变化的影 响;引用Thinking in java中的例子:
- class Tank {
- int level;
- }
- public class Assignment {
- 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 = 22 ;
- System.out.println("3: t1.level: " + t1.level +
- ", t2.level: " + t2.level);
- }
- } /* Output:
- 1: t1.level: 9, t2.level: 47
- 2: t1.level: 47, t2.level: 47
- 3: t1.level: 22, t2.level: 22
- */ //:~
class Tank { int level; } public class Assignment { 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 = 22; System.out.println("3: t1.level: " + t1.level + ", t2.level: " + t2.level); } } /* Output: 1: t1.level: 9, t2.level: 47 2: t1.level: 47, t2.level: 47 3: t1.level: 22, t2.level: 22 *///:~
从输出可看出,由于赋值操作的是一个对象的引用,所以修改t1的同时,也改变了 t2,这是由于t1和t2包含的是相同的引用,指向一个相同的对象。