博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Java中的对象和引用

Posted on 2017-02-28 14:12  one_stone  阅读(83)  评论(0编辑  收藏  举报

 本文主要任务:区分对象和引用的区别

 一般面试题中都会考Java传参的问题,并且它的标准答案是Java只有一种参数传递方式:那就是按值传递,即Java中传递任何东西都是传值。如果传入方法的是基本类型的东西,你就得到此基本类型的一份拷贝。如果是传递引用,就得到引用的拷贝。

public class ObjectRef {  
  
    //基本类型的参数传递  
  
    public static void testBasicType(int m) {  
  
        System.out.println("m=" + m);//m=50  
  
        m = 100;  
  
        System.out.println("m=" + m);//m=100  
  
    }  
  
  
    //参数为对象,不改变引用的值 ??????  
  
    public static void add(StringBuffer s) {  
  
        s.append("_add");  
  
    }  
  
  
    //参数为对象,改变引用的值 ?????  
  
    public static void changeRef(StringBuffer s) {  
  
        s = new StringBuffer("Java");  
  
    }  
  
  
    public static void main(String[] args) {  
  
        int i = 50;  
  
        testBasicType(i);  
  
        System.out.println(i);//i=50  
  
        StringBuffer sMain = new StringBuffer("init");  
  
        System.out.println("sMain=" + sMain.toString());//sMain=init  
  
        add(sMain);  
  
        System.out.println("sMain=" + sMain.toString());//sMain=init_add  
  
        changeRef(sMain);  
  
        System.out.println("sMain=" + sMain.toString());//sMain=init_add  
  
    }  
  
}  

  以上程序的允许结果显示出,testBasicType方法的参数是基本类型,尽管参数m的值发生改变,但并不影响i。

     add方法的参数是一个对象,当把sMain传给参数s时,s得到的是sMain的拷贝,所以s和sMain指向同一个对象,因此,使用s操作影响的其实就是sMain指向的对象,故调用add方法后,sMain指向的对象的内容发生了改变。

     在changeRef方法中,参数也是对象,当把sMain传给参数s时,s得到的是sMain的拷贝,但与add方法不同的是,在方法体内改变了s指向的对象(也就是s指向了别的对象,牵着气球的绳子换气球了),给s重新赋值后,s与sMain已经毫无关联,它和sMain指向了不同的对象,所以不管对s做什么操作,都不会影响sMain指向的对象,故调用changeRef方法前后sMain指向的对象内容并未发生改变.

      对于add方法的调用结果,可能很多人会有这种感觉:这不明明是按引用传递吗?对于这种问题,还是套用Bruce Eckel的话:这依赖于你如何看待引用,最终你会明白,这个争论并没那么重要。真正重要的是,你要理解,传引用使得(调用者的)对象的修改变得不可预期。 

 

 public   class   Test  
{   public int   i,j;    
    public   void   test_m(Test   a)  
    {     Test   b   =  new   Test();  
          b.i   =   1;  
          b.j   =   2;  
          a   =   b;  
    }  
    public   void   test_m1(Test   a   )  
    {     a.i   =   1;  
        a.j   =   2;  
    }  
    public   static   void   main(String   argv[])  
    {     Test   t=   new   Test();  
          t.i   =   5;  
          t.j   =   6;  
          System.out.println( "t.i   =   "+   t.i   +   "   t.j=   "   +   t.j); //5,6  
          t.test_m(t);  
          System.out.println( "t.i   =   "+   t.i   +   "   t.j=   "   +   t.j); //5,6,a和t都指向了一个对象,而在test_m中s又指向了另一个对象,所以对象t不变!!!  
  
          t.test_m1(t);  
  
          System.out.println( "t.i   =   "+   t.i   +   "   t.j=   "   +   t.j); //1,2  
  
    }  
  
}  

  

    答案只有一个:Java里都是按值传递参数。而实际上,我们要明白,当参数是对象时,传引用会发生什么状况(就像上面的add方法)? 

 楼主,这样来记这个问题 

  如下表达式: 
    A a1 = new A(); 
   它代表A是类,a1是引用,a1不是对象,new A()才是对象,a1引用指向new A()这个对象。

    在JAVA里,“=”不能被看成是一个赋值语句,它不是在把一个对象赋给另外一个对象,它的执行过程实质上是将右边对象的地址传给了左边的引用,使得左边的引用指向了右边的对象。JAVA表面上看起来没有指针,但它的引用其实质就是一个指针,引用里面存放的并不是对象,而是该对象的地址,使得该引用指向了对象。在JAVA里,“=”语句不应该被翻译成赋值语句,因为它所执行的确实不是一个赋值的过程,而是一个传地址的过程,被译成赋值语句会造成很多误解,译得不准确。

   再如: 
   A a2; 
  它代表A是类,a2是引用,a2不是对象,a2所指向的对象为空null; 

   再如: 
   a2 = a1; 
  它代表,a2是引用,a1也是引用,a1所指向的对象的地址传给了a2(传址),使得a2和a1指向了同一对象。 

   综上所述,可以简单的记为,在初始化时,“=”语句左边的是引用,右边new出来的是对象。 

   在后面的左右都是引用的“=”语句时,左右的引用同时指向了右边引用所指向的对象.

    再所谓实例,其实就是对象的同义词。

 

参考:http://zwmf.iteye.com/blog/1738574

        http://www.cnblogs.com/dolphin0520/p/3592498.html

tsxf