Home arrow Java arrow Page 9 - Java in Review
JAVA

Java in Review


Tired of hearing about the gory syntax details of Java? Keep reading for a more conceptual view of the language, focusing on important issues that deserve more attention than they usually receive. Even an advanced programmer will find useful information in this article. It was excerpted from chapter one of Hardcore Java, edited by Robert Simmons Jr. (O'Reilly, 2004; ISBN: 0596005687).

Author Info:
By: O'Reilly Media
Rating: 4 stars4 stars4 stars4 stars4 stars / 12
June 16, 2005
TABLE OF CONTENTS:
  1. · Java in Review
  2. · Syntax Issues
  3. · Collection iteration with for
  4. · Labels
  5. · Assertions versus exceptions
  6. · Assertions and deployment
  7. · Initialization
  8. · Access Issues
  9. · Common Mistakes

print this article
SEARCH DEVARTICLES

Java in Review - Common Mistakes
(Page 9 of 9 )

There are a certain group of mistakes in Java programming that are made over and over again at hundreds of companies throughout the world. Knowing how to avoid these mistakes will make you stand out from the crowd and look like you actually know what you are doing.

System Streams

The Java System streams represent the ability to write to the console or to read from it. When you invoke a method such as printStackTrace( ) with no arguments, its output is written to the default System stream, which is usually the console that started the program. However, these streams can cause problems in your code. Consider the following from a hypothetical GUI:

  public void someMethod(){
    try {
      // do a whole bunch of stuff
    } (catch Exception ex) {
     
ex.printStackTrace();
      throw new MyApplicationException();
    }
  }

To debug this GUI, you print the stack trace if something goes wrong. The problem is that the code will print the stack trace to the console window, which may be hidden, or even running on another computer.

Printing to the console window is iffy, at best, in enterprise Java. In fact, there are times when you cannot use the console at all, such as when you write EJB code. At other times, you may be writing a library for others to use, and not have any idea of what the runtime environment is. Therefore, since one of your prime goals should be to promote reusability, you cannot count on the console always being around. The solution to the problem is to keep throwing those exceptions.

In JDK 1.4, there is a new facility that will tell you if one exception caused another. This is called the Chained Exception Facility. In short, if you throw an exception inside of a catch block, the virtual machine will note the exception that you are throwing, along with the exception and stack trace that caused you to enter the catch block in the first place. For more information on this facility, consult the JDK documentation at http://java.sun.com/j2se/1.4.1/docs/relnotes/
features.html#chained
-exceptions
. The basics of using the chained exception facility are illustrated in this code block:

  public void someMethod(){
    try {
      // do a whole bunch of stuff
    } (catch IllegalAccessException ex) {
      throw new MyApplicationException();
    }
  }

This version of the method takes advantage of chained exceptions by responding to the initial IllegalAccessException by throwing a new exception (MyApplicationException). The exceptions will keep propagating through the application until some code decides to catch them. When you finally do print the trace (presumably through a GUI, rather than a console window!), you will see that MyApplicationException was caused by IllegalAccessException, and the correct stack trace will be indicated.

Feel free to use the System streams in main( ) methods and in other classes in which you control their runtime environment. While you wouldn’t want to use it in your application’s data model classes, it may be acceptable for a GUI’s frame window class.

When logging errors and debugging traces are inside a program or library, a much better solution is to use a logging package, which is much more robust. The Log4J package from Jakarta (http://jakarta.apache.org/log4j/docs/index.html) will allow you to print your exception messages in a configurable way, as shown in Example 1-12.

Example 1-12. Log4J as an alternative to the System streams

  import org.apache.log4j.Logger
 
class SomeClass {
   
/** Logger for this class. */
    private final static Logger LOGGER = Logger.getLogger(SomeClass.class);
   
public void someMethod() {
      try {
        // do a whole bunch of stuff
     
} (catch Exception ex) {
        LOGGER.error("Failure in SomeMethod", ex);
        throw new MyApplicationException();
     
}
    }
  }

The benefit to the altered approach shown here is that you can route the output to whichever stream you desire. You can send the output to an XML file, relay it to another application via JMS, create an email to the system administrator, or even dump the information to /dev/null (though there’s really no good reason to ever do this!). Using a logging package gives you far more flexibility than Java’s System streams could ever provide.

Ultimately, using the System streams is okay only if you are writing a console-based application; for error handling, I wouldn’t advise them at all. Also, tools and libraries should never write directly to System streams. Instead, they should pass errors and exceptions up to application-specific code that will do the logging for them.

System.exit( )

Every now and then you will encounter a third-party library that has code such as the following:

  if (someSeriousErrorCondition){
    System.exit(-1);
  }

This code looks really benign, but watch out! It’s a wolf in sheep’s clothing. The problem here is that if you are a user of this library, you may not want the entire application to close because of this error. For example, if you are using this library as a part of a plug-in to another product, you should have only the plug-in crash and not the entire tool platform.

However, System.exit() crashes the entire application in an exceedingly brutal and bloody fashion. Just imagine the look of surprise, consternation, and growing anger on the face of your users when they try to run the plug-in, and their application simply exits without bothering to save two hours’ worth of data. Although it sounds funny, it could lead to sore feet from looking for another job.

If you use System.exit( ) at all, your best bet is to use it only in the main method. If you ever write a library and embed System.exit() into it, you probably deserve any resulting physical violence.


If you think this sort of thing doesn’t happen in real life, you are in for a brutal surprise. While developing a scripting support plug-in for Eclipse, I found that the Jython libraries embed System.exit() in their code. This resulted in a very long debugging session in which I tried to figure out what the heck I did to get Eclipse to simply die. One more bug report filed; at least I’m an expert at Bugzilla now.

Default Execution

One common mistake I see developers make is shown in the following code:

  if (source == yesBtn) {
    processYesBtn();
  } else if (source == noBtn) {
    processNoBtn();
  } else {
    processCancelBtn();
  }

In this code, the developer has three buttons in his panel. The if structure is designed to process the buttons if the user clicks on them. If the user clicks on yesBtn, then the first branch will be executed; if the user clicks on noBtn, then the second branch will be executed. Otherwise, the user must have clicked on cancelBtn.

However, there is one small problem. A junior programmer added a new button and registered the panel as an action listener. Unfortunately, he forgot to add handler code for the button. Now, when the user presses Load Favorites, the dialog simply doesn’t work. The user subsequently files a bug report that reads something like, “When I try to load favorites, it doesn’t work. ” However, your JUnit test works fine (because you don’t depend on the action handling).

Now you get to spend 12 hours stepping through all 2,000 lines of code related to loading favorites. Eventually, you will detect the missing handler and feel an irresistible compulsion to toss your computer out the window.

Close that window and implement a coding standard instead. Change your if statements to look like the following:

  if (source == yesBtn){
    processYesBtn();
  } else if (source == noBtn) {
    processNoBtn();
  } elseif (source == cancelBtn){
   
processCancelBtn();
 
} else {
    assert false : source.toString()
;
  }

Those of you who studied the “assert” section probably saw this coming. The point I am trying to make here is to never use else clauses or default blocks in switch statements to perform specific tasks without checking your assumptions. If your if-then-else statement or switch statement is dealing with an enumerated set of values, go ahead and enumerate them; in your default or final else clause, throw an error.


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