2013-03-03 24 views
0

当我通过Java代码进行调试时,我经常看到很多对我来说在我的应用程序中很有用的属性,以便让他们获得它们并对它们做些什么,但是我看看API或javadocs,该类没有任何这样的属性或getter方法来获取这些属性值。例如:在调试器中具有属性但没有getter方法的Java对象

myPhoneCallObj.foo has value "bar" in debugger 
myPhoneCallObj.baz has value otherObj which in turn has other values like otherObj.baz 

我也不会在Java做的事:

String myValue = myPhoneCallObj.foo 

,因为它不会在Java的编译,但在Groovy中,我可以写上面的代码和运行过程中,它得到我所需要的价值。在Java代码中如何做到这一点?

myPhoneCallObj是Java Interface PhoneCall的一个实例,调试器将此类型显示为PhoneCallImpl(接口的第三方实现)类型。我无法访问该第三方的源代码以查找理解,但Interface具有用于API的完整文档和Javadoc。

回答

1

给定一个类,如:

class X 
{ 
    private int value; 

    @Override 
    public String toString() 
    { 
     return (Integer.toString(value)); 
    } 
} 

你可以这样做:

import java.lang.reflect.Field; 


public class Test 
{ 
    public static void main(final String[] argv) 
     throws NoSuchFieldException, 
       IllegalArgumentException, 
       IllegalAccessException 
    { 
     final X x; 

     x = new X(); 
     System.out.println(x); 
     changeValue(x); 
     System.out.println(x); 
    } 

    private static void changeValue(final X x) 
     throws NoSuchFieldException, 
       IllegalArgumentException, 
       IllegalAccessException 
    { 
     final Class<X> clazz; 
     final Field field; 

     clazz = X.class; 
     field = clazz.getDeclaredField("value"); 
     field.setAccessible(true); 
     field.set(x, Integer.MAX_VALUE); 
    } 
} 

这里的关键是说,即使到field.setAccessible(true);通话value是私人允许它被访问。

但是,通常有一个原因为什么字段是私人的,如果您的代码与您正在操作的第三方代码的更高版本中断,您不应该感到惊讶。

+0

+1了解详情。所以eclipse调试器使用Java反射来获取对象的所有值,即使它们是私有的? – ace 2013-03-03 17:15:09

+0

那一个我不知道,有一个调试器API - IDE调试器可能使用的http://docs.oracle.com/javase/7/docs/technotes/guides/jvmti/index.html。调试器API可能会暴露所有这些东西。 – TofuBeer 2013-03-03 17:17:28

0

这些属性是私有还是保护范围?您可以直接访问的唯一属性是公共属性,但所有变量都将显示在调试对象检查器中。

0

如果您绝对需要获取该值,则可以使用反射。 (这很可能是什么Groovy中做)

相关问题