是否有可能从Android/Java或iPhone/objective-C中的代码中获取变量名以进行调试
我经常使用定义如下的常量:是否有可能从Android/Java或iPhone/objective-C中的代码中获取变量名以进行调试,java,android,objective-c,Java,Android,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 na
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: " + ????);
输出:
“这是常数名为myConstant_x的任何变量的调试输出”
而不是
Log.i (TAG,"this is debug output of anyVariable with constant name: " + anyVariable);
输出:
“这是常数名为1的任何变量的调试输出”
有办法吗
我知道可以从代码中获得方法名,但是有没有办法也获得变量名呢
会很有帮助的
谢谢
编辑:更新/更正示例代码-很抱歉第一个误导性版本您可以使用反射获取类的字段并对其进行迭代。然后您就可以访问名称和值
Log.i (TAG,"this is debug output of anyVariable with constant name: " + ????);
大概是这样的:
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 );
}
}
}
NSLog(@"The value of %s is %d", NameAndValue(myConstant_x));
public void logStaticFields(类clazz)抛出IllegalAccessException{
for(字段f:clazz.getDeclaredFields()){
if(Modifier.isStatic(f.getModifiers())){
布尔值wasaccessable=f.isAccessible();
f、 setAccessible(true);
Log.i(标记“这是静态字段的调试输出”+f.getName()+”:“+f.get(null));
f、 setAccessible(wasaccessable);
}
}
}
如果只想记录常量(通常是静态最终值),可以检查Modifier.isStatic(f.getModifiers())&&Modifier.isFinal(f.getModifiers())
此方法还临时禁用访问检查,否则get()
可能会抛出IllegalAccessException
。请注意,根据JVM的SecurityManager
配置,这可能仍然不起作用
请注意,这仅适用于字段(类或实例变量)和方法参数,而不适用于方法中的局部变量,因为这些变量没有反射信息。编译代码时,编译器会内联常量。在运行时(即在JAR或可执行二进制文件中),它们不再存在,而是为它们的值而存在。这就是为什么你试图做的不会奏效 对于Java,当您在Eclipse中搜索常量时(使用Strg-Shift-G),可以看到这一点。您会收到一条警告,告诉您此搜索可能不适用于没有源代码的库,因为常量的名称不是以二进制形式存储的。 当然,您可能可以通过使用反射和其他技巧来解决其中一些情况,但我不确定这是否值得为一件像日志记录这样简单的事情而费心。反射是缓慢的,通常是复杂的,并且是新错误的好来源
至于C/Objective-C,我很确定,不存在这样的工具,但我不会因此而被拘留:)在Objective-C中,您可以定义一个宏:
#define NameAndValue(v) #v, v
然后像这样使用它:
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 );
}
}
}
NSLog(@"The value of %s is %d", NameAndValue(myConstant_x));
当然,如果
myConstant\u x
不是一个int
,您需要使用适当的格式说明符,而不是%d
,谢谢-这看起来非常好-但是我如何得到这个contant(就像我的示例myConstant\u x)而不是它们的列表或者我遗漏了什么?@user387184好吧,你可以使用getDeclaredField(name)
获取字段,但是在这种情况下,你为什么不直接将名称添加到日志消息中,跳过所有与反射有关的麻烦呢?…哦,对不起,我想我犯了一个错误-实际上我有一个由常量赋值的变量,在记录变量的值而不是值时,我需要常量的名称-很抱歉。但是我可以使用你发布的方法——只需要找到带有值的名称。对吗?我还试图调用logStaticFields(MyClass),但我得到了一个编译器错误:常量无法解析为变量-虽然我可以只传递一个类名?@user387184您可以查找具有给定值的常量,但如果多个常量具有相同的值,则会出现歧义。由于常量是内联的,所以您不知道它实际上是哪一个。至于编译器错误:您必须使用MyClass.class
作为参数。非常感谢!超级棒,我用你的方法成功了。这大大简化了调试我的代码!我不知道这个?我写#v#是什么意思?在这种情况下不能-为什么?记录枚举名会更容易吗?为什么不使用枚举而不是常量?有关更多信息,请参阅。我知道这个问题是8年前提出的。但是,如果有人想做与OP相同的事情,请考虑是否真的需要在日志中使用变量名。因为名称只是一个指向实际变量的指针,可以在缩小代码或其他方式的同时进行更改。