Java应用程序的调试/标准版本

时间:2009-05-15 15:12:50

标签: java debugging

问候,

我正在使用嵌入式java,我将应用程序写入低资源设备。我得到的一个问题是当代码崩溃时设备停止。我可以通过我添加的一些日志记录从中获取一些信息。 (简单的打印陈述)

由于内存限制,此日志记录无法保留在应用程序中。

我想知道是否有人知道我可以传递给JVM的一个标志,如果它是我需要的调试或标准编译则说明。

如果是调试版本,我希望包含print语句,如果它是删除print语句的标准版本。我问,因为我要经常剪切和粘贴语句等(这是一个痛苦的)

由于

3 个答案:

答案 0 :(得分:8)

您可以利用if (constant)由编译器优化的事实。

在名为DEBUG的地方创建一个全局变量:

public static final boolean DEBUG = true;

然后像这样进行日志记录:

if (DEBUG) {
    System.out.println("Debug");
}

要禁用调试,只需将DEBUG更改为false,编译器将优化所有日志记录语句。您可以通过使用javap -c查看生成的字节码来验证这一点。

例如:

class DebugTest {
    public static final boolean DEBUG = true;
    public static void main(String[] args) {
        if (DEBUG) {
            int a = 10;
            System.out.println("a = " + a);
        }
    }
}

编译为:

Compiled from "DebugTest.java"
class DebugTest extends java.lang.Object{
public static final boolean DEBUG;

DebugTest();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   bipush  10
   2:   istore_1
   3:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   6:   new #3; //class java/lang/StringBuilder
   9:   dup
   10:  invokespecial   #4; //Method java/lang/StringBuilder."":()V
   13:  ldc #5; //String a = 
   15:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   18:  iload_1
   19:  invokevirtual   #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   22:  invokevirtual   #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   25:  invokevirtual   #9; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   28:  return

}

DEBUG更改为false会产生:

Compiled from "DebugTest.java"
class DebugTest extends java.lang.Object{
public static final boolean DEBUG;

DebugTest();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   return

}

答案 1 :(得分:1)

嗯,你必须使用预处理器,但它仍然是一种丑陋。

在编译之前预先处理您的源代码。例如,使用cpp

据说javac有时可能会删除死区条件中的语句,包括静态最终布尔值,如

private static final DEBUG = false;

if(DEBUG) System.err.println("Entered");

但我不确定,我建议你尝试一下,检查字节码是否包含该电话。

答案 2 :(得分:1)

是否必须从标准版本中删除日志记录语句,或者只是无法启用它们?

如果它只是后者,那么只需将日志语句包装在if-check中,就像其他答案所提到的那样。

无论您做什么,都不要继续将代码复制/粘贴到项目中 - 自动执行该手动工作。节省时间。