Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否有可能从Android/Java或iPhone/objective-C中的代码中获取变量名以进行调试_Java_Android_Objective C - Fatal编程技术网

是否有可能从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相同的事情,请考虑是否真的需要在日志中使用变量名。因为名称只是一个指向实际变量的指针,可以在缩小代码或其他方式的同时进行更改。