java left logo
java middle logo
java right logo
 

Home
 
 
Main Menu
Home
Java Tutorials
Book Reviews
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Java Network
Java Forums
Java Blog




Most Visited Tips
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Book Reviews
Top Rated Tips
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Book Reviews


Statistics
Registered Users: 3947
Java SE Tips: 614
Java ME Tips: 202
Java EE Tips: 183
Other API Tips: 779
Java Applications: 298
Java Libraries: 209
Java Games: 16
Book Reviews:
 
 
 
Introducing Annotations E-mail
User Rating: / 91
PoorBest 

This Tech Tip reprinted with permission by java.sun.com

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.

Copyright (c) 2004-2005 Sun Microsystems, Inc.
All Rights Reserved.


 Related Tips

 
< Prev   Next >

Page 1 of 0 ( 0 comments )

You can share your information about this topic using the form below!

Please do not post your questions with this form! Thanks.


Name (required)


E-Mail (required)

Your email will not be displayed on the site - only to our administrator
Homepage(optional)



Comment Enable HTML code : Yes No



 
       
         
     
 
 
 
   
 
 
java bottom left
java bottom middle
java bottom right
RSS 0.91 FeedRSS 1.0 FeedRSS 2.0 FeedATOM FeedOPML Feed

Home - About Us - Privacy Policy
Copyright 2005 - 2008 www.java-tips.org
Java is a trademark of Sun Microsystems, Inc.