关于java中的等号操作符“=”

  我们都知道,“=”等号操作符在编码语言中是个神奇的符号,因为它表示赋值操作而不是单纯的“等于”。我们也知道,“=”进行赋值操作时,有左值和右值的说法,当然左值和右值这里就不详述了,这个不是本文的重点。那么,下面,简单对java中的“=”操作符进行一下简单的说明:

  首先,java中的数据类型分为两大类,基本类型和引用类型,基本类型:intbytecharshortlongfloatdoubleboolean。引用类型:StringArrayObject

  那么先比较下面两段代码:
1.
1 int a = 3;
2 int b = a;
3 b++;
4 System.out.println(a);

 2.

1 String a = "Hello";
2 String b = a;
3 b = b + "World";
4 System.out.println(a);
最终的结果将是上面的a = 3; a = "Hello"; 表面上看a的值都没有改变但实际上两者的机制是不一样的。
 
  对基本类型进行“=”只是一个赋值操作,就是将a这个变量进栈,并将a的内存区域的内容设成3
  而引用类型进行“=”却是引用操作,说具体一些就是地址的传递,开始我们String a = "Hello";时,实际上是堆中开辟了一块内存,内存中存放的内容是字符串"Hello"对象, 而变量a却是我们在栈中声明的,这个“=”操作符是让a去引用"Hello"这个对象,a真正的值应该是"Hello"字符串对象的地址!而String b = a; 时;这时候是将a的地址赋值给了b(引用是地址的赋值),ab的值都是同一个地址,那么ab指向的是同一个对象,b = b + "world"; 实际上改变了b所引用的对象,不是b所引用的对象的值b重新引用了另外一个对象"Helloworld"a还是引用"Hello"这个字符串对象。当然System.out.println(a)的值不会改变(这个,笔者暂时理解成为println方法传递引用类型对基本类型的一个重载,感兴趣的可以查阅一下javadoc,这个还有待验证)。
  拓展一下,讲一下java的内存回收机制,以下面的一段代码为例:
1 String a = "Hello";
2 a = a + "World";
3 System.out.println(a);
  看一下a = a + "World";这句,我们前面已经知道了a是对堆中某块内存对象的引用,a + "World";给我们的第一反应就是将这块内存中的改为"HelloWorld",实际则不然,"Hello"这个String类型的对象在初始化后就已经是不可变的了,a = a + "World";实际上是在堆区另外开辟一块内存,内存中的内容是"HelloWorld",原来存放"Hello"的那块内存区域会被回收,a重新引用"HelloWorld"这块内存区域,a的值(a的地址)也会改变。
  再看一个例子:
 1 public class Text{
 2     private String word;
 3     public void setWord(String Word){
 4         this.word = Word;
 5     }
 6     public void printWord(){
 7         System.out.println(this.word);
 8     }
 9 }
10 public class Main{
11     public static void main(String[] args){
12         Text t1 = new Text();
13         t1.setWord("Hello");
14         Text t2 = t1;
15         t2.setWord("HelloWorld");
16         t1.printWord();
17     }
18 }
t1.printWord()输出的却是"HelloWorld";说明在Text t2 = t1;时,t2引用了t1所引用的对象,就是new Text()初始化的对象,t2.setWord("HelloWorld");时,这个对象的成员word被改变了,就是说t2.word引用的对象的地址变了,但是t1t2引用的由new Text();初始化的这个对象却没有改变,因为t1还引用原来的对象,t1.word也会改变。
  最后用一句话总结:变量可以引用对象,但是变量不是对象!
posted @ 2013-04-14 17:34  FingerDancing  阅读(3772)  评论(0编辑  收藏  举报