Java
  Home arrow Java arrow Page 5 - Java in Review
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
JAVA

Java in Review
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 3 stars3 stars3 stars3 stars3 stars / 5
    2005-06-16

    Table of Contents:
  • Java in Review
  • Syntax Issues
  • Collection iteration with for
  • Labels
  • Assertions versus exceptions
  • Assertions and deployment
  • Initialization
  • Access Issues
  • Common Mistakes

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Java in Review - Assertions versus exceptions


    (Page 5 of 9 )

    One of the most common questions asked about assertions is why you should bother using them when you can perform these checks and indicate errors with exceptions.

    First of all, the code doing the check may be far more complicated than a simple check for null. In fact, the body of assertion expressions can easily be as much work for the processor as the body of the method itself. If you use exceptions, then these checks will be performed every time the method is called. In a production system, this can add significant overhead.

    On the other hand, with assertions, the virtual machine can be set to ignore the assertions. As a result, their processing time is near zero. In development mode, during testing, or during diagnosis of some nasty problem, you can turn on assertions and figure out the problems. Once the software is stable, you can turn off assertions and gain a performance boost. As a bonus, assertions offer a shorthand that makes your code look more elegant.


    Assertions are off by default and have to be turned on manually.

    To assert or not to assert

    Deciding whether to use assertions or exceptions is a decision that you have to take on a case-by-case basis. Here are some tips that will help you make the right decisions:

    • Don’t use assertions to validate parameters of public functions. These functions should throw NullPointerException, IllegalArgumentException, and other relevant exceptions instead. Since public functions will be used by other programmers, you should make sure that they get the right errors if they mess up.

    • Use assertions to check preconditions and postconditions on parameters of protected and private access methods.

    • Don’t use assertions to check for software user errors. If you expect the user of your web-based online sales system to enter a 10-digit credit card number and she enters only 9 digits, don’t use an assert. Instead, throw IllegalArgumentException. If you use assert, as soon as someone turns off assertions on your servlet container, the checking logic in your system would go away.

    • Use assertions to check parameters and variables for conditions that shouldn’t happen. For example, consider the following event handler method:

      package oreilly.hcj.review;
     
    public class Assertions {
       
    public void mouseClicked(final MouseEvent event){
          Object source = event.getSource();
          assert(source != null);
         
    int hc = source.hashCode();
          // ...do code using source
        }
      }

    The virtual machine should never pass null as a source for a mouse event. However, just to be sure, the user asserts it. The granularity of assertions that you should use here is something of a judgment call. If you assert everything, you will have to write a lot more code; however, your code will be rock solid.

    • Use assertions to check for invalid code branches. For example, consider the following GUI class:

      package oreilly.hcj.review;
     
    public class Assertions {
      package oreilly.hcj.review;
     
    import java.awt.event.ActionEvent;
      import javax.swing.JButton;
     
    public class SomeGuiPanel {
       
    private JButton cancelBtn;
        private JButton noBtn;
        private JButton yesBtn;
       
    public void actionPerformed(final ActionEvent event) {
          Object source = event.getSource();
          assert (source != null);
         
    if (source == yesBtn) {
            // ...do code
          } else if (source == noBtn) {
            // ...do code
          } else if (source == cancelBtn) {
            // ...do code
          } else {
           
    assert false : "Invalid Source " + source.toString();
         
    }
        }
      }

    In this class, the action handler expects the user to click on one of three buttons. The method doesn’t expect there to be any other buttons to which the class is listening. However, if a developer added a new button but forgot to change the handler, there would be an extra button to deal with. On the final else clause, the method checks to make sure there aren’t any other buttons by using assert. If the emphasized line is hit, the program will generate an assertion exception. In this case, using assert is much more elegant than using throw.


    Some may object that the program should always throw an irrecoverable error at this point regardless of whether assertions are enabled. This is a valid point. However, in a production environment, that is not always a good idea. The accountants using your software wouldn’t know what an AssertionError is. Instead, when the program crashes, they are likely to give you an informative bug report such as, “It crashed while I was making my finance report. ” Its better to use assertions so the program can at least limp along if something weird happens. Let the developers and QA people deal with the assertion errors.

    • Don’t use an assertion to do any work. Assertions are developer-level errors and shouldn’t be used to repair state in the program or perform complex logging. Also, don’t forget that if a user runs the program without assertions, the code will be gone. If that code was critical to the functioning of the program, you could be in deep trouble.

    • Don’t bother internationalizing assertion error messages. Again, since assertions are developer-level issues, internationalizing them would be a waste of time.

    • Use assertions to check post conditions. If you create a method and expect that it will never to return null to the user, you might write something like the following:

      package oreilly.hcj.review;
     
    public class SyntaxIssues {
       
    protected Object someHelperMethod() {
         
    Object result = null;
         
    // ...do some code that sets result.
         
    assert (result != null); // check post condition.
         
    return result;
        }
      }

    In this code, the method checks the return value against a post-condition before returning the value. If the value is still null after all of the work, the assertion will toss an error.

    Now that you have a good idea of when to use assert and when not to, apply what you have learned on an actual class:

      package oreilly.hcj.review;
     
    import java.awt.event.MouseEvent;
      import java.util.Arrays;
      import java.util.Iterator;
      import java.util.List;
     
    public class Assertions {
       
    public static void main(final String[] args) {
         
    helperParseArgs(args);
         
    Iterator iter = System.getProperties()
                              .keySet()
                              .iterator();
          for (String key = null; iter.hasNext(); key = (String)iter.next()) {
            assert (key != null);
            System.out.println(key + "=" + System.getProperty(key));
         
    }
        }
       
    protected static void helperParseArgs(final String[] args) {
         
    assert (args != null);
          assert (!Arrays.asList(args)
                         .contains(null));
         
    //
    --
          List arglist = Arrays.asList(args);
          Iterator iter = arglist.iterator();
          for (String argument = null;
               
    iter.hasNext();
                argument = (String)iter.next()) {
            if (argument.startsWith("-D")) {
             
    if (argument.length() < 3) {
                int idx = arglist.indexOf(argument);
                throw new IllegalArgumentException("Argument" + idx
                       
    + " is not a legal property argument.");
              }
             
    int valueIdx = argument.indexOf('='); 
              System.setProperty(argument.substring(2, valueIdx),
                             argument.substring(valueIdx + 1));
              
    assert (System.getProperty(
              argument.substring(2, valueIdx))
                    .equals(argument.substring(valueIdx + 1)));
           
    }
          }
        }
      }

    In this code, you have a method that parses the arguments to the program and looks for system properties to set. If it encounters an argument such as -Dmy.property=5 on the command line, it will set the system property my.property to the value 5.

    The method that does the actual work is a protected helper method that checks the arguments to the method for validity using assertions. You should also note that the second check to the method takes quite a bit of work to accomplish since the list has to go through and see whether there are any nulls in the argument list. At production time, however, this work will be removed by turning off assertions. Inside the for loop, the method doesn’t use an assertion if the user gives a bad property name because this is an error made by the user of the program and not by the developers of the program.

    Finally, the last assert statement checks that the system property was actually set properly. Notice that this assert does the exact same string manipulation work as the original setting of the system property. Some performance-minded developers may catch on to this fact and get the bright idea to store the key and value at each iteration of the loop, as shown here:

      package oreilly.hcj.review;
     
    public class Assertions {
     
    for (String argument = null; iter.hasNext(); argument = (String)iter.next()) {
       
    if (argument.startsWith("-D")) {
          if (argument.length() < 3) {
           
    int idx = arglist.indexOf(argument);
           
    throw new IllegalArgumentException("Argument" + idx
                              + " is not a legal property argument.");
          }
          int valueIdx = argument.indexOf('=');
         
    String key = argument.substring(2, valueIdx);
         
    String value = argument.substring(valueIdx + 1);
          
    Sys
    ystem.setProperty(key, value);
          assert (System.getProperty(key).equals(value));
        }
      }

    Although this will work, it is a bit wasteful. The extra allocations of the key and value variables are needed only if assertions are enabled. If assertions are disabled, then these variables will be used only once. Whether to use variables to store parts of an assertion is a judgment call. If the code that is creating the variable is very long, a variable may be the best bet. If the code is simple, you should just save yourself the extra allocations at production time.

    More Java Articles
    More By O'Reilly Media


     

    Buy this book now. This article was excerpted from chapter one of Hardcore Java, edited by Robert Simmons Jr. (O'Reilly, 2004; ISBN: 0596005687). Check it out at your favorite bookstore. Buy this book now.

    JAVA ARTICLES

    - 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 ...
    - Generics and Limitations in Java
    - Getting Started with Java Web Development in...






    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 5 hosted by Hostway
    Stay green...Green IT