2011-06-22 276 views
7

我想知道如何垃圾收集工作时,你有一个类与反射用于获取一些字段值。 JVM如何意识到这些字段引用的值是可访问的,因此当前不使用正式语言语法访问垃圾回收时不适合进行垃圾回收?垃圾收集和反射

一个小片段显示问题(虽然反射一直过分强调这里):

/** 
* 
*/ 

import java.lang.reflect.Field; 

public class B { 
    protected B previous = null, next = null; 

    /** 
    * 
    */ 
    public B(B from) { 
     this.previous = from; 
    } 

    public void transition(B to) { 
     this.next = to; 
    } 

    public B next() { 
     try { 
      Field f = getClass().getField("next"); 
      f.setAccessible(true); 
      try { 
       return (B)f.get(this); 
      } finally { 
       f.setAccessible(false); 
      } 
     } catch (Exception e) { 
      throw new IllegalStateException(e); 
     } 
    } 

    public B previous() { 
     try { 
      Field f = getClass().getField("previous"); 
      f.setAccessible(true); 
      try { 
       return (B)f.get(this); 
      } finally { 
       f.setAccessible(false); 
      } 
     } catch (Exception e) { 
      throw new IllegalStateException(e); 
     } 
    } 
} 

干杯,
克里斯

+0

有趣的问题。它是否受某种嵌入式Java应用程序的启发? –

+0

你能否给我们一个代码片段来澄清你的意思:“一个带反射的类用于获取一些字段值?” –

+0

实际上,我正在进行网络框架的测试,并且有些字段是通过反射来访问的。想知道反射如何影响内存使用,也许JVM保留对象是不确定的。 –

回答

10

如果您正在访问一个实例的领域,那么你会仍然需要参考该实例。对于那种情况,GC没有任何异常。

+0

谢谢,这很有道理:) –

5

要访问对象的字段,您必须具有对该对象的引用。如果您通过反射或直接访问它,对于是否有强烈的对象引用没有任何影响。

1

这是一个奇怪的测试案例:你使用反射来访问“this”。根据定义,“this”在声明类的实例方法中使用时是活的,因此不会被GCed。

但更重要的一点是,反射只是允许你在已经有引用的对象中操作字段等。这是关键 - 如果您可以反映实例进行检查,您显然仍然有一个对象的参考,因此它保持活着。