是否有可能从Android / Java或iPhone / objective-C中的代码中获取变量名称以进行调试
我经常使用如下定义的常量:
private static final int myConstant_x = 1; private static final int myConstant_y = 2; private int anyVariable; anyVariable = myConstant_x
在调试期间,以某种方式访问日志输出的变量名称而不是值是非常有用的。
Log.i (TAG,"this is debug output of anyVariable with constant name: " + ????);
输出: “这是具有常量名称的anyVariable的调试输出:myConstant_x”
代替
Log.i (TAG,"this is debug output of anyVariable with constant name: " + anyVariable);
带输出: “这是具有常量名称的anyVariable的调试输出:1”
有什么办法吗?
我知道可以从代码中获取方法名称,但有没有办法以某种方式获取变量名称?
会非常有帮助的
谢谢
编辑:更新/更正示例代码 – 抱歉第一个误导性版本
您可以使用reflection获取类的字段并迭代它们。 然后,您可以访问名称和值。
像这样的东西:
public void logStaticFields( Class> clazz) throws IllegalAccessException { for( Field f : clazz.getDeclaredFields() ) { if( Modifier.isStatic( f.getModifiers() ) ) { boolean wasAccessible = f.isAccessible(); f.setAccessible(true); Log.i (TAG, "this is debug output of static field " + f.getName() + ": " + f.get( null ) ); f.setAccessible( wasAccessible ); } } }
如果您只想记录常量(通常是静态最终),您可以检查Modifier.isStatic( f.getModifiers() ) && Modifier.isFinal( f.getModifiers() )
。
此方法还会暂时禁用访问检查,否则get()
可能会抛出IllegalAccessException
。 请注意,这可能仍然不起作用,具体取决于JVM的SecurityManager
配置。
请注意,这仅适用于字段(类或实例变量)和方法参数,而不适用于方法中的局部变量,因为它们没有reflection信息。
在Objective-C中,您可以定义一个宏:
#define NameAndValue(v) #v, v
并像这样使用它:
NSLog(@"The value of %s is %d", NameAndValue(myConstant_x));
当然,如果myConstant_x
不是int
,则需要使用适当的格式说明符而不是%d
。
编译代码时,编译器会内联常量。 在运行时(即在JAR或可执行二进制文件中),它们不再存在,而是它们的值。 这就是为什么你要做的事情无法奏效。
对于Java,当您在Eclipse中搜索常量时(使用Strg-Shift-G),可以看到这一点。 您会收到一条警告,告诉您此搜索可能不适用于您没有源代码的库,因为常量的名称不会以二进制forms存储。 当然,您可以通过使用reflection和其他技巧来解决其中一些案例,但我不确定这对于像日志这样简单的事情来说是值得的。 反思很慢,而且通常很复杂,也是新错误的良好来源。
至于C / Objective-C我很确定,没有这样的设施存在,但我不会因此而被认为:)