Home arrow Java arrow Page 7 - The Final (Constants) Story
JAVA

The Final (Constants) Story


Generally, it is better to swap a logic error for a compiler error. Compiler errors can be found quickly and fixed just as quickly, whereas logic errors can take thouands of man-hours to find and fix. This article explains how to use the Java keyword final to change logic errors into compiler errors, thus saving you an enormous amount of time. It is excerpted from chapter two of Hardcore Java, written by Robert Simmons Jr. (O'Reilly, 2004; ISBN: 0596005687).

Author Info:
By: O'Reilly Media
Rating: 4 stars4 stars4 stars4 stars4 stars / 8
October 20, 2005
TABLE OF CONTENTS:
  1. · The Final (Constants) Story
  2. · Excessive Constants
  3. · Deferred Initialization
  4. · Final Collections
  5. · Instance-Scoped Variables
  6. · Final Methods
  7. · Conditional Compilation Variable Location

print this article
SEARCH DEVARTICLES

The Final (Constants) Story - Conditional Compilation Variable Location
(Page 7 of 7 )

When implementing conditional compilation, the question of where to put these compilation variables always comes up. There are many potential solutions to the problem, but you need to watch out for a couple of pitfalls.

First of all, putting a variable in the top-level package of your product is probably not a good idea. The problem is that there may be other classes in this package as well. Since all classes will be referencing this package, you could accidentally create circular package dependencies.


Circular dependencies arise when Package A depends on Package B, which in turn depends on Package A. Circular dependencies make it very difficult to separate code into components, and circular references make code fragile by allowing bugs to migrate across the dependencies into other packages.


 

Your best bet is to create a new package in each of your major products. If you are an employee of a Sun, for example, each major product would be defined by the package directly undercom.sun. I like to create a package named_developmentunder the major packages of my clients’ products. The leading underscore helps me remember that this package is not part of the product base but is instead a container for things such as these variables. Inside this new package, place a class namedDevelopmentMode.

In this class, install one variable for each package in your product. Then you can simply import the class and access the appropriate variable. For the Hardcore Java example code, the class would look something like the following.

package oreilly.hcj._development;
public final class DevelopmentMode {
 
/** Development mode constant for package oreilly.hcj.bankdata. */
 
public static final boolean hcj_bankdata = true;
 
/** Development mode constant for package oreilly.hcj.bankdata. */
  public static final boolean hcj_collections = true;
 
/** Development mode constant for package oreilly.hcj.bankdata. */
  public static final boolean hcj_constants = true;
 
/** Development mode constant for package oreilly.hcj.bankdata. */
  public static final boolean hcj_datamodeling = true;
 
/** Development mode constant for package oreilly.hcj.bankdata. */
  public static final boolean hcj_exceptions = true;
 
/** Development mode constant for package oreilly.hcj.bankdata. */
  public static final boolean hcj_finalstory = true;
 
/** Development mode constant for package oreilly.hcj.bankdata. */
  public static final boolean hcj_immutable = true;
  /** Development mode constant for package oreilly.hcj.bankdata. */
  public static final boolean hcj_nested = true;
 
/** Development mode constant for package oreilly.hcj.bankdata. */
  public static final boolean hcj_proxies = true;
 
/** Development mode constant for package oreilly.hcj.bankdata. */
  public static final boolean hcj_references = true;
 
/** Development mode constant for package oreilly.hcj.bankdata. */
  public static final boolean hcj_review = true;
 
private DevelopmentMode() {
    assert false: "DevelopmentMode is a Singleton.";
  }
}

In this class, you don’t specify theoreillypackage because it would be a bit redundant, since all the code you would be writing for your company would be in that package. However, the variable naming here is a matter of taste. The important fact is that all packages can be turned from development to deployment mode in one place. Using the constant is easy:

package oreilly.hcj.finalstory;
import oreilly.hcj._development.DevelopmentMode;
public class ConditionalCompile {
 
public void projectVariables(){
    if (DevelopmentMode.hcj_finalstory) {
      // ...do conditional code.
    }
  }
}

You merely use the constant in the same way it was used in the last section. This allows you to take advantage of conditional compilation in a maintainable manner. However, be careful not to place any malfunctioning code into the_developmentpackage (or whatever you named your package), or you may create circular package dependencies. The_developmentpackage shouldn’t depend on anything other than third-party libraries and the JDK itself.

Using final as a Coding Standard

I imagine that many of you never thought you would see an entire chapter written on a single keyword. However, this particular keyword is quite useful. I strongly advise that you spread final all over your code. You should use it so much that not seeing it becomes a rare, if not completely unknown, occurrence.

This coding standard may take a little getting used to but it will really pay off in the long term. The best way to get started is to force yourself to usefinalheavily whenever you write or edit code. Also, you should force the junior developers working for you to adopt the use offinalas a coding standard. They may grumble and balk for a bit, but the coding standard will quickly become so automatic that the developers won’t consciously think about it.

Like good Javadoc habits, this one is much easier to implement if you do it while you are coding. Having to go back through old code to implement the standard is a real pain. For this reason, I suggest you make it a coding standard starting today. If you have tools that allow you to edit the code templates, edit them to introducefinaleverywhere you can. Also, when you edit someone else’s code, introduce thefinalvariable liberally. Doing so helps to guarantee that no one can mess up your code without actually trying to do so.


DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

blog comments powered by Disqus
JAVA ARTICLES

- Java Too Insecure, Says Microsoft Researcher
- Google Beats Oracle in Java Ruling
- Deploying Multiple Java Applets as One
- Deploying Java Applets
- Understanding Deployment Frameworks
- Database Programming in Java Using JDBC
- Extension Interfaces and SAX
- Entities, Handlers and SAX
- Advanced SAX
- Conversions and Java Print Streams
- Formatters and Java Print Streams
- Java Print Streams
- Wildcards, Arrays, and Generics in Java
- Wildcards and Generic Methods in Java
- Finishing the Project: Java Web Development ...

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials