1. package com.lj.test; 
  2.  
  3. class Number{ 
  4.     int i; 
  5. public class Test { 
  6.      
  7.     public static void main(String[] args) { 
  8.         Number n1 = new Number(); 
  9.         Number n2 = new Number(); 
  10.         n1.i = 9
  11.         n2.i = 47
  12.         System.out.println("1:n1.i="+n1.i+",n2.i="+n2.i); 
  13.         n1 = n2; 
  14.         System.out.println("2:n1.i="+n1.i+",n2.i="+n2.i); 
  15.         n1.i = 27
  16.         System.out.println("3:n1.i="+n1.i+",n2.i="+n2.i); 
  17.     } 

猜猜结果会是啥样呢?

1:n1.i=9,n2.i=47

2:n1.i=47,n2.i=47
3:n1.i=27,n2.i=27

 

开始我们实例化了两个对象n1和n2,并且对其i值都赋予相应的值。然后吧n2赋值给n1,再修改n1。在很多别的编程语言里,你可以设想n1和n2自始至终都是两个独立的对象。但在Java里面,对n1的修改会影响到n2!我们可以看出这时n1和n2使用同一块内存,而原来的n1对象所占用的内存则会被垃圾回收器清理掉。我个人认为,我们在赋值操作时经常会马虎的认为会输出结果:3:n1.i=27,n2.i=47。

 

下面我参考Thinking in Java 3rd Edition又做个了例子发现,在方法调用的时候,传递参数时也要注意:

 

 
  1. package com.lj.test; 
  2.  
  3. class Number{ 
  4.     int i; 
  5. public class Test { 
  6.     public static void f(Number n){ 
  7.         n.i = 88
  8.     } 
  9.     public static void main(String[] args) { 
  10.         Number n3 = new Number(); 
  11.         n3.i = 33
  12.         System.out.println("n3.i:"+n3.i); 
  13.         f(n3); 
  14.         System.out.println("n3.i:"+n3.i); 
  15.     } 

输出结果为:

n3.i:33

n3.i:88

 

通过两个例子我总结一下吧,在基础类型的赋值时是对值的复制操作,而对对象的赋值则是内存地址引用操作(包括以对象为参数的也是内存地址的引用操作),当多个对象都引用了此内存地址时,其中任何一个对象发生改变 其他引用同一块内存的对象也会受到影响。