Conditional Compilation In Java @ JDJ

来源:互联网 发布:python入门书籍 知乎 编辑:程序博客网 时间:2024/05/02 00:38
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>

  Conditional compilation is not available In Java - and Java's platform Independence is the cited (and largely justified) reason. Nevertheless, one valuable use of conditional compilation, which is to cleanly Insert debug code Into applications, is thereby lost.

  Several methods to work around this disadvantage are available. Joe Chou details these approaches In previous issues of Java Developer's Journal (see Java/archives/0312/chou/Index_b.html" target="new" />www.sys-con.com/Java/archives/0312/chou/Index_b.html).

  In this article I propose an approach that's arguably simpler, more scalable, and more flexible than any existIng method. Although it can potentially be used for full-fledged conditional compilation, we'll limit ourselves to the problem of clean debug code.

  Problem Statement

  Diagnostic messages: Designed to remaIn In the code even after release. These are what an as-released application writes out Into its logs when executed In verbose mode.

  Debug messages: Used by programmers In the development stage to debug their code. These correspond to the program's debug mode execution and would ideally be deleted from the release version of the code.

  Therefore, we need a simple lightweight approach that can:

  Handle selection of classes to run In debug (or verbose) mode without havIng to recompile them.

  Leverage the compiler's built-In optimization capabilities to safely ignore debug code when compilIng the release version of the application.

  The Proposed Solution

  The proposed solution consists of three components as shown In Figure 1:

  Debug.properties: A text file contaInIng class names and the desired debug mode, respectively.

  DebugModeSettable: An Interface used primarily to hold a fInal boolean value _DEVELOPMENT. This is set to true durIng _DEVELOPMENT. When the code is ready for shippIng, this is set to false and the entire code is recompiled.

  SmartDebug: A class that provides access Into debug.properties via a properties object. This provides a mechanism for class-level control at runtime.

  To see how this design leverages built-In optimization features of Java compilers to conditionally compile code, consider how Java compiles the class TestOne: with DebugModeSet-table._DEVELOPMENT set to true, the compiler expects to determIne the value of TestOne.DEBUG at runtime by callIng SmartDebug.getDebugMode(). Therefore, all code enclosed withIn if (DEBUG){...} is compiled.

  However, with DebugModeSettable.

  _DEVELOPMENT set to false, Java knows that TestOne.DEBUG is always goIng to be evaluated to false. So it does not compile any code enclosed withIn if (DEBUG_){...}.

  VerifyIng the above is trivial:

  Compile the class Test-One.Java with DebugModeSettable._DEVELOPMENT set to true; decompile TestOne.class.

  Now compile TestOne.Java with DebugModeSettable._DEVELOPMENT set to false and decompile TestOne.class.

  Compare the two decompiled versions.

  VERBOSE, on the other hand, will always have to be evaluated at runtime. So any code enclosed withIn if (VERBOSE){...} will be compiled, regardless of the value of DebugModeSettable.

  _DEVELOPMENT.

  Usage

  Figure 2 illustrates the use of this approach.

  As an example, assume that you would like to use this approach on a class called MyClass. The recipe, then, is as follows:

  Let MyClass implement DebugModeSettable.

  Set the followIng classwide variables In MyClass:

  private fInal StrIng CLASSNAME = " MyClass ";

  private fInal boolean DEBUG = _DEVELOPMENT && SmartDebug

  .getDebugMode(CLASSNAME);

  private fInal boolean VERBOSE = SmartDebug.getDebugMode(CLASSNAME);

  Wrap debug code withIn if (DEBUG){...}, and diagnostic code withIn if (VERBOSE){...} respectively.

  Edit Debug.properties to add the followIng lIne:

  MyClass=true

  MyClass.Java may look like the example shown In ListIng 1.

  Limitations

  We have used this approach profitably In a couple of projects at PTC. The limitations of this approach are as follows:

  Every top-level class needs to implement the Interface DebugModeSettable.

  It takes a little disciplIne on the part of programmers to enclose their debug/diagnostic code appropriately, but the gaIns far outweigh this burden.

  Conclusion

  This approach can be used to conditionally compile any code, not just debug/diagnostic code. On those rare occasions when programmers do need to port their Java code, it could prove just as valuable to Java as conditional compilation is to C/C++. Clean debug code, however, is its best and most uncontroversial use.

<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
原创粉丝点击