在java中打印变量名和变量值的方法

时间:2014-08-01 09:25:28

标签: java

String activityState = "resume";
DebugLog(activityState)

void DebugLog(String obj1) {}

如何让DebugLog像这样打印:

activityState : resume

我曾经在调试时在很多地方写了很多print语句作为日志。我会写一些像

这样的陈述
System.out.println("activityState : " + activityState);

我想要一个方法来打印变量名和变量值。在C ++中,可以像下面这样完成:

#define dbg(x) cout<< #x <<" --> " << x << endl ;

有没有办法做到这一点?

提前致谢。

3 个答案:

答案 0 :(得分:1)

获取变量名称没有直接的解决方案。

但是,在您有许多字段并且不想手动打印其状态的上下文中,您可以使用反射。

这是一个简单的例子:

class MyPojo {
    public static void main(String[] args) {
        System.out.println(new MyPojo());
    }

    int i = 1;
    String s = "foo";

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        for (Field f: getClass().getDeclaredFields()) {
            try {
            result
            .append(f.getName())
            .append(" : ")
            .append(f.get(this))
            .append(System.getProperty("line.separator"));
            }
            catch (IllegalStateException ise) {
                result
                .append(f.getName())
                .append(" : ")
                .append("[cannot retrieve value]")
                .append(System.getProperty("line.separator"));
            }
            // nope
            catch (IllegalAccessException iae) {}
        }
        return result.toString();
    }
}

<强>输出

i : 1
s : foo

答案 1 :(得分:1)

您可以使用java Reflection获取变量名称和值。这是一个示例代码;

public class Example{

  String activityState = "resume";

  public static void main(String[] args) {

       Example example = new Example();
       Class<?> c = example.getClass();
       Field field = c.getDeclaredField("activityState");
       System.out.println(field.getName());
       System.out.println(field.get(example));
  }    

}

答案 2 :(得分:1)

由于这是用于调试的,您可以使用instrumentation with aspectj,您的代码在调试输出语句中保持干净,您可以根据需要忽略该方面。

定义set(FieldPattern)点切割以捕获所有场分配(连接点)

public aspect TestAssignmentAspect {

    pointcut assigmentPointCut() : set(* *);

    after() : assigmentPointCut() {
        System.out.printf("%s = %s%n", thisJoinPoint.getSignature().getName(),
                String.valueOf(Arrays.toString(thisJoinPoint.getArgs())));
    }
}

这是Test class

public class Test {

    public static String activityState = "stopped";

    public static void main(String[] args) {
        activityState = "start";

        doSomething();

        activityState = "pause";

        doSomeOtherthing();

        activityState = "resume";

        System.out.printf("the end!%n");
    }

    private static void doSomeOtherthing() {
        System.out.printf("doing some other thing...%n");
    }

    private static void doSomething() {
        System.out.printf("doing something...%n");
    }
}

如果您使用编织的方面运行此示例,则输出将为

activityState = [stopped]
activityState = [start]
doing something...
activityState = [pause]
doing some other thing...
activityState = [resume]
the end!

解释

pointcut assigmentPointCut() : set(* *);

set点切换以捕获分配,点连接,任何具有任何名称的变量,也可以在示例中

pointcut assigmentPointCut() : set(String activityState);

advice,给定点切割时所需的行为匹配

after() : assigmentPointCut() { ... }

可以使用特殊参考thisJoinPoint访问有关点连接的信息。