java Reference garbage collector

本文通过实例探讨Java中数组作为参数传递时的引用机制,解释了改变数组引用地址后,外部数组为何未发生变化,深入解析Java中数组对象的传递方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们用实例来说明问题: 

示例代码1: 
/** 
  *   该类将说明将数组作为参数传递过程中,引用机制所起到的作用 
  */ 
class   testArray   { 
    /** 
      *   打印数组的内容,并显示该数组的引用地址 
      */
    static   void   printArray(   int[]   array   )   { 
        System.out.println(   "The   array 's   address:   "   +   array   ); 

        for(   int   i   =   0;   i   <   array.length;   i++   ) 
            System.out.print(   "   "   +   array[i]   ); 
        System.out.println(); 
    } 
    
    /** 
      *   企图通过该函数对所传递的数组进行改变 
      */
    static   void   changeArray(   int[]   a1   )   { 
        System.out.println(   "array   a1   in   changeArray:   "   +   a1   ); 
    
        int[]   b   =   {   1,   2,   3   }; 
        System.out.println(   "\nCreate   array   b... "   ); 
        printArray(   b   ); 
        
        System.out.println(   "\nafter   a1   =   b... "   ); 
        a1   =   b; 
        System.out.println(   "array   a1 's   address   :   "   +   a1   +   "\n "); 
    } 
    
    /** 
      *   主函数,实例化一个int   array,并查看其在调用changeArray()   method前 
      *   与调用后内部数据的变化以及引用地址的变化。 
      */ 
    public   static   void   main(   String[]   args   )   { 
        System.out.println(   "------------   Start   Process   ------------ "   ); 
        int[]   a   =   {   3,   2,   1   }; 
        System.out.println(   "Create   array   a...   "   ); 
        printArray(   a   ); 
        
        System.out.println(   "\nCall   changeArray   methods. "); 
        changeArray(   a   );         //   期望通过引用传递改变数组a的内容 
        
        System.out.println(   "After   call   changeArray   methods...(back   main()   method) "   ); 
        System.out.println(   "The   array   a   is   not   changed... "   ); 
        printArray(   a   ); 
    } 
}   ///   @.@||~ 

运行结果... 
------------   Starting   Process   ------------ 
Create   array   a... 
The   array 's   address:   [I@15601ea 
    3   2   1 

Call   changeArray()   methods... 
In   changeArray(),   array   a1 's   address:   [I@15601ea 

Create   array   b... 
The   array 's   address:   [I@197d257 
    1   2   3 

after   a1   =   b... 
a1 's   address:   [I@197d257 

after   call   changeArray   methods...(back   main()   method) 
The   array   a   is   not   changed... 
The   array 's   address:   [I@15601ea 
    3   2   1 


总结: 
这里我们可以很清楚的看到,虽然我们将数组a以引用传递的方式传递给了changeArray()   method,并且在开始时changeArray()   method中的int[]   a1确实依然指向原先的对象,但是当我们改变了a1的指向,将其指向另一个新的数组b时, 

注意,注意,问题出现了,我们很自然的会和c\c++做参考,于是我们认为,由于此时a1(也就是方法内部的引用)发生了改变,同时就会引起 
外部数组的改变,但是当我们回到main()函数时,数组a没有发生热和变化,我们可以看到a的引用依然指向原先的对象,这是为什么呢? 

是的,在JAVA中,数组依然是一个对象,对象就会以reference的形式传递,但是这个reference却是一个值传递, 
我们先搞清楚 
Tyep   a   =   new   Type(); 
这里a   is   a   reference,   他指向一个Type   Object,JAVA中突出了一个引用变量的概念,reference本身也是一种变量,所以reference本身以值传递的形式传送给某个method, 
----------------------------------------------------------------------------- 
重点 
这时   changeArray()中的int[]   a1   与   main()中的int[]   a乃是两个同时引用同一个long   array   object的不同的reference, 
------------------------------------------------------------------------------ 
当我们修改了changeArray()中的int[]   a的指向时,并不会影响另一个reference的指向,这就是为什么没有发生改变的原因了。 


如果欲在此地同时改变两者就必须实际改变两者所引用的对象。 
源代码如下: 
class   testArray   {
    static   void   printArray(   int[]   array   )   { 
        System.out.println(   "The   array 's   address:   "   +   array   ); 

        for(   int   i   =   0;   i   <   array.length;   i++   ) 
            System.out.print(   "   "   +   array[i]   ); 
        System.out.println(); 
    } 

    static   void   changeArray(   int[]   a1   )   { 
        System.out.println(   "array   a1   in   changeArray:   "   +   a1   ); 
    
        int[]   b   =   {   1,   2,   3   }; 
        System.out.println(   "\nCreate   array   b... "   ); 
        printArray(   b   ); 
        
        /*   Don 't   do   this,以下代码只是改变了reference   a1   的指向,并位改变a1原先引用之对象的内部状态 
          *   System.out.println(   "\nafter   a1   =   b... "   ); 
          *   a1   =   b; 
          *   System.out.println(   "array   a1 's   address   :   "   +   a1   +   "\n "); 
          */ 
        //   实际改变Object 
        for(   int   i   =   0;   i   <   a1.length;   i++   ) 
            a1[i]   =   b[i]; 
    } 

    
    public   static   void   main(   String[]   args   )   { 
        System.out.println(   "------------   Start   Process   ------------ "   ); 
        int[]   a   =   {   3,   2,   1   }; 
        System.out.println(   "Create   array   a...   "   ); 
        printArray(   a   ); 
        
        System.out.println(   "\nCall   changeArray   methods. "); 
        changeArray(   a   );         //   期望通过引用传递改变数组a的内容 
        
        System.out.println(   "After   call   changeArray   methods...(back   main()   method) "   ); 
        System.out.println(   "The   array   a   is   not   changed... "   ); 
        printArray(   a   ); 
    } 
}   ///   @.@||~ 

运行结果... 
------------   Starting   Process   ------------ 
Create   array   a... 
The   array 's   address:   [I@15601ea 
    3   2   1 

Call   changeArray()   methods... 
In   changeArray(),   array   a1 's   address:   [I@15601ea 

Create   array   b... 
The   array 's   address:   [I@197d257 
    1   2   3 

after   call   changeArray   methods...(back   main()   method) 
The   array   a   is   changed... 
The   array 's   address:   [I@15601ea 
    1   2   3 

我们可以看到main()   method中的array   a确实发生了改变。


2 garbage 与reference

Java 提供自动内存管理的机制,也就是俗称的 garbage collection(垃圾收集)。当一个对象不再被任何 variable (Reference) 所指到,就代表此对象从此不可能再被利用,Java 虚拟机器内一个负责收集垃圾的 thread 就会在适当的时机出来将此块内存回收。

后来对reference进行了补充(关于debugger的困扰)

Direct Reference > Soft Reference > Weak Reference > Phantom Reference 
其中,direct reference 就是一般的 reference。只要被任何 direct reference 所reference 到的对象就不会被 garbage collector 清除。其它的三种 reference(包括soft reference,weak reference,phantom reference)则不然,他们不会影响 gar bage collection。 

如果对这些特殊的 reference 感兴趣,具体去看看 java.lang.ref 的 Javadoc,顺便写几个程序试试看。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值