Tech all over the world
Wednesday, June 21, 2006
  Core Java Technologies Tech Tips, June 20, 2006 (Annotations, Quiz)

Sun Microsystems, Inc.
  Core Java Technology
  Technical Tips
  In This Issue
June 20, 2006 

Welcome to the Core Java Technologies Tech Tips for June 20, 2006. Here you'll get tips on using core Java technologies and APIs, such as those in Java 2 Platform, Standard Edition (J2SE).

This issue covers:

» Introducing Annotations
» Tech Tips Quiz

These tips were developed using Java 2 Platform, Standard Edition Development Kit 5.0 (JDK 5.0). You can download JDK 5.0 at http://java.sun.com/j2se/1.5.0/download.jsp.

This issue of the Core Java Technologies Tech Tips is written by John Zukowski, president of JZ Ventures, Inc.

See the Subscribe/Unsubscribe note at the end of this newsletter to subscribe to Tech Tips that focus on technologies and products in other Java platforms.
 

  INTRODUCING ANNOTATIONS  

J2SE 5.0 introduced many new language features. These include support for generics and the enhanced for loop. Previous Tech Tips covered generics and the enhanced for loop. Another important new feature in J2SE 5.0 is annotations. This tip explores the annotations that are built into J2SE 5.0.

First, what is an annotation? Defined as part of JSR 175: A Metadata Facility for the Java Programming Language, annotations offer a way to associate metadata with program elements (such as classes, interfaces, and methods). They can be thought of as additional modifiers without changing the generated bytecode for those elements.

The concept of introducing metadata to source code isn't new with J2SE 5.0. You can add an @deprecated tag to a method's javadoc comments and the compiler treats this as metadata about the method. This ability has been in place since the 1.0 release of J2SE. The initial release of the platform already had deprecated methods, with the getenv() method of System (though this wasn't in the Java Language Specification until the 1.1 addendum). The concept is almost the same now, at least the @ part of the syntax. Only the location has changed -- an annotation tag goes in source, not comments. The main point here is that annotations are a systematic way to support a declarative programming model.

This leads to the first annotation that comes with J2SE 5.0: @Deprecated. Notice the capital D here. Functionally, @Deprecated in source works the same as @deprecated in the javadoc associated with a class or method. By flagging methods with the @Deprecated tag, you're alerting the compiler to warn the user when the method or class is used.

The following Main class has a method named deprecatedMethod() that is flagged with the @Deprecated annotation and a, @deprecated comment:

  public class Main {

    /**
    * @deprecated Out of date. Use System.foobar() instead.
    */

    @Deprecated
    public static void deprecatedMethod() {
      System.out.println("Don't call me");
    }
  }

You compile a class with annotations the same way as you do for one without annotations:

> javac Main.java

As expected, this produces Main.class.

If you use the deprecated method, it produces a compilation-time warning -- just like using the @deprecated tag in a javadoc. Here's an example:

  public class User {
    public static void main(String args[]) {
      Main.deprecatedMethod();
    }
  }

Compile the class:

> javac User.java

and you'll see the following warning about using a deprecated method:

  Note: User.java uses or overrides a deprecated API.
  Note: Recompile with -Xlint:deprecation for details.

Adding the -Xlint to the compilation line shows specifically what is wrong:

> javac -Xlint:deprecation User.java

  User.java:3: warning: [deprecation] deprecatedMethod() in
  Main has been deprecated
         Main.deprecatedMethod();
             ^

  1 warning

The change from the @deprecated comment to the @Deprecated annotation doesn't introduce anything really new to the system. It only slightly changes the way of doing the same thing. The other two new annotations available to the J2SE 5.0 platform, @Override and @SuppressWarnings, do introduce new functionality to the platform.

The @Override annotation can be used with method declarations. As its name implies, you use the @Override annotation to flag a method that is supposed to override a method of the superclass. Why use it? To catch errors sooner. How many times have you meant to override a method, but either misspelled the method name, specified the wrong arguments, or had a different return type? In other words, how often have you defined a new method when what you really wanted to do was override an existing one? By using @Override, you'll find the problem in the following class sooner rather than later:

  public class Overrode {
    @Override
    public int hashcode() {
      return 0;
    }

    @Override
    public boolean equals(Object o) {
      return true;
    }
  }

The problem here is that the method name should be hashCode, not hashcode. Suppose the method declaration is buried in the source for a much larger class definition. Without the first @Override annotation, how long would it take you to realize that your hashCode() method (with camel-case for spelling, not all lowercase) is not being called, and you're getting the default behavior of the parent Object class? Thanks to the @Override annotation, compiling the class produces a compile time error, alerting you to the problem:

> javac Overrode.java

Overrode.java:2: method does not override a method from its
superclass
      @Override
       ^
1 error

The sooner you can find errors of this nature, the cost of correction becomes drastically reduced. Note that the hashCode() method should never return a constant. For a fuller description of the proper usage of hashCode() and equals(), see Item 8 in the book Effective Java Programming Language Guide by Joshua Bloch.

The final of the three new annotations in J2SE 5.0, @SuppressWarnings, is the most interesting. It tells the compiler not to warn you about something that it would normally warn you about. Warnings belong to a category, so you have to tell the annotation what types of warnings to suppress. The javac compiler defines seven options to suppress: all, deprecation, unchecked, fallthrough, path, serial, and finally. (The language specification defines only two such types: deprecation and unchecked.)

To demonstrate, let's look at the suppression of the fallthrough option. Let's start with the following class. Notice that the class is missing a break statement for each case of the switch statement:

  public class Fall {
    public static void main(String args[]) {
      int i = args.length;
      switch (i) {
        case 0: System.out.println("0");
        case 1: System.out.println("1");
        case 2: System.out.println("2");
        case 3: System.out.println("3");
        default: System.out.println("Default");
      }
    }
  }

Compile the class with javac. You'll see that it simply creates the .class file, and displays no warnings:

javac Fall.java

If you want the compiler to warn you about switch statements that fall through (that is, one or more break statements are missing), you compile with the -Xlint:fallthrough option:

javac -Xlint:fallthrough Fall.java

This produces the following warnings:

   Fall.java:6: warning: [fallthrough] possible fall-through into case
      case 1: System.out.println("1");
      ^
   Fall.java:7: warning: [fallthrough] possible fall-through into case
      case 2: System.out.println("2");
      ^
   Fall.java:8: warning: [fallthrough] possible fall-through into case
      case 3: System.out.println("3");
      ^
   Fall.java:9: warning: [fallthrough] possible fall-through into case
      default : System.out.println("Default");
      ^
   4 warnings

But what if you want to ignore the fact that the switch statement is missing a break statement for each case? That's where the @SuppressWarnings annotation comes into play. If you add the following line before the main() method declaration:

   @SuppressWarnings("fallthrough")

Compiling the class with the -Xlint:fallthrough option:

   javac -Xlint:fallthrough Fall.java

will just generate the .class file and display no warnings.

@SuppressWarnings annotations can also be used to suppress other warnings such as those that would be displayed if you used a collection without specifying the data type of the collection elements. Don't use the @SuppressWarnings annotation simply to avoid the compilation-time warning. Use it where an unchecked warning is unavoidable, such as when using a library that isn't built with generics in mind.

That's really about it for the built-in annotations. However one additional thing to note, annotations (with any arguments) are typically specified on a line by themselves.

There is much more that can be done when you define your own annotations, rather than using the ones already defined in J2SE 5.0. For information on defining annotations see Annotations.

Back to Top
 

  TECH TIPS QUIZ  

One of the items in the September 13, 2005 issue of the Tech Tips was a Tech Tips quiz. Many people enjoyed the challenge of the quiz. Others commented about how good it was to get pointers to some of the older tips. Here's another short quiz that tests your knowledge of some topics covered in past Tech Tips. You can find the answers at the end of the quiz.

  1. How do you enable JOptionPane components to play auditory cues?

    1. For each component to enable, create a subclass of JOptionPane and call its setAuditoryCuesEnabled() method.
    2. Set the AuditoryCues.playList property of UIManager to the cue list to use for all option panes.
    3. Call the static setAuditoryCuesEnabled() method of JOptionPane to enable cues for all option panes.
    4. Call the static setAuditoryCuesEnabled() method of System to enable cues for all parts of the platform.

  2. In the following program, what's the value of the variable printed?

      public class Foo {
        private static ThreadLocal<Integer> threadLocal =
          new ThreadLocal<Integer>() {
            protected synchronized Integer initialValue() {
              return new Integer(0);
          }
        };

        public static void main(String args[]) {
          Runnable runner = new Runnable() {
            public void run() {
              threadLocal.set((Integer)threadLocal.get() + 1);
            }
          };
          for (int i=0; i<3; i++) {
            Thread t = new Thread(runner);
            t.start();
          }
            System.out.println("Value is " + threadLocal.get());
        }
      }

    1. 0
    2. 1
    3. 2
    4. 3

  3. When using reflection, which class do you use to construct an instance of a class?

    1. Constructors
    2. Method
    3. Field
    4. Class

  4. The Image I/O library provides support for reading and writing various image formats. Which format is newly supported with J2SE 5.0?

    1. GIF
    2. WBMP
    3. TIF
    4. SVG

  5. When using the Java 3D API, which class is the primary class used to create a scene graph?

    1. Graphics3D
    2. Static3D
    3. Canvas3D
    4. Transform3D
Answers
  1. How do you enable JOptionPane components to play auditory cues?

    1. Set the AuditoryCues.playList property of UIManager to the cue list to use for all option panes. See the January 22, 2004 Tech Tip Beyond the Basics of JOptionPane to learn about this setting and how to set cues for individual actions.

  2. In the following program, what's the value of the variable printed?

    1. 0. The ThreadLocal variable is updated in threads other than the main thread so it is always zero in the main thread. For more information on the use of ThreadLocal variables, see the December 8, 2003 Tech Tip ThreadLocal Variables for Storing Thread-Specific State Information.

  3. When using reflection, which class do you use to construct an instance of a class?

    1. Class. You can use either a Constructor class (not constructors) or a Class class to construct a class. See the January 10, 2004 Tech Tip Using Reflection To Create Class Instances for more information about class construction with reflection.

  4. The Image I/O library provides support for reading and writing various image formats. Which format is newly supported with J2SE 5.0?

    1. WBMP. J2SE 5.0 includes support for the BMP and WBMP formats. Support for reading GIF files has been available since J2SE 1.0. But support for writing GIF files isn't available until Java SE 6. For more on the Image I/O library, see the February 17, 2004 Tech Tip Loading and Saving Images with the Image I/O Library.

  5. When using the Java 3D API, which class is the primary class used to create a scene graph?

    1. Canvas3D. The Java 3D API is an optional J2SE API and now a community source project. For more information about the Java 3D API, see the October 14, 2003 Tech Tip An Introduction to the Java 3D API and the July 16, 2004 Tech Tip Lighting a 3D Scene.

Back to Top
 

  DEVELOPER ASSISTANCE  

Need programming advice on Java SE? Try Developer Expert Assistance.
 







 
Comments: Post a Comment



<< Home
News, Articles, events from all over the world

My Photo
Name:
Location: India

Born on shraavana shudha chauthi of dundubhi naama samvaswara, Im kiran alias kini alias kiri bought up by loving parents. Being from agricultural family I have learnt plowing, carting but never learnt climbing trees. Now away from home I have lost touch with the agricultural skills.

ARCHIVES
January 2006 / February 2006 / March 2006 / April 2006 / May 2006 / June 2006 / July 2006 / August 2006 / September 2006 / October 2006 / November 2006 / December 2006 / April 2007 / May 2007 / June 2007 / July 2007 / August 2007 / September 2007 / October 2007 / November 2007 / December 2007 / January 2008 / February 2008 / March 2008 / April 2008 / May 2008 / June 2008 / July 2008 / August 2008 / September 2008 / October 2008 / November 2008 / December 2008 / January 2009 / February 2009 / March 2009 / April 2009 /


Powered by Blogger