Forum Controls
Spotlight Features

The Rich Engineering Heritage Behind Dependency Injection

Andrew McVeigh takes us on a tour of the rich heritage behind dependency injection, what it represents, and tells us why its here to stay.

NetBeans 6: Matisse Updates

NetBeans 6 delivers great updates to the Matisse GUI builder. Spend a few minutes with Roman Strobl and get an expert briefing on what's new and what has changed.

Introduction to Groovy Part 3

In this, the third and final installation of Andres' Introduction to Groovy series, you learn about how Groovy handles variable numbers of arguments, named parameters, currying, and more about Groovy operators. Including, some new operators.

Easier Custom Components with Swing Fuse

Swing Fuse (actually just Fuse), is a framework designed to make it easier to create your own custom desktop components. In this article, Daniel Spiewak shows you how to get started and provides sample source code you can download.

Benchmark Analysis: Guice vs Spring

Willam Louth shows how he uses JXInsight Probes to investigate probable performance issues with code bases that he is not familiar with. He also highlights possible pitfalls in creating a benchmark, as well as in the analysis of results.
Replies: 1 - Pages: 1  
  Click to reply to this thread Reply

Annotations: Utilizing the Standard Annotations

At 10:44 PM on Feb 15, 2005, R.J. Lorimer wrote:

I'd like to start a trend today by beginning to post on one of the less discussed features of Java 5 - Annotations. Annotations are a very powerful tool, and they are beginning to get a lot of varied use in the community. Javalobby recently ran a tutorial on a tool called TestNG that is a revision of the ideas behind jUnit using annotations. If you haven't checked it out, I highly recommend it. In the near future I'd like to describe how to develop your own annotations, and how you can use them in a practical sense, concerning yourself with the intended target, the retention policy, and runtime interpretation of those annotations. Annotations don't have to be something you tackle entirely on your own, however. Java has three built-in annotations for classes specifically - @Deprecated , @Override , and @SuppressWarnings . Today I plan to do my best to describe the usage of each.

@Deprecated

@Deprecated is the complement to the pre-Java-5 ' @deprecated ' Javadoc tag. @Deprecated annotations can be applied to any program element for annotations. In the annotation world, that includes all enumeration values in the java.lang.ElementType enumeration (another annotation Type, a constructor, a field, a local variable, a method, a package, a parameter, and a type). As far as I have seen, however, the only elements currently recognized by the compiler are the ones I list below (with the exception of deprecated annotations, which I have omitted). Applying the deprecation annotation to an element is easy as pie:

// class
@Deprecated
public class SomeClass {
 
 // field
 @Deprecated
 public int field;
 
 // constructor
 @Deprecated
 public SomeClass() {
 
 }
 
 // method
 @Deprecated
 public void method() {
   
 }
}

Practically speaking, the compiler will warn for these annotations the same way it did prior to Java 5 when it found the Javadoc tag. Annotations have an entire API around them, however, and as we will see later, that allows for a lot of different custom behaviors to be defined by you as a developer (or by other developers).

@Override

@Override is designed specifically for the compiler to use (later we will learn that this relates to a retention policy of level 'SOURCE'). Use of the @Override tag defines that a method is meant to override a method from a superclass. This is a relatively simple way to ensure at compile time (rather than later at runtime) that the method you have defined does, in fact, override functionality. When is this a problem? Well, commonly people find a mistake in method overriding at runtime when subclass behavior isn't being executed when a method is invoked on a class. There are essentially two ways that this can happen - 1.) the method name was misspelled somehow, 2.) the method was supplied different parameters. Here are two examples:

// trying to override toString
public String toStirng() { ... }// misspelled
public String toString(String arg1) { ... } // wrong args

... and here is a class using the @Override tag that won't compile until we fix our little typo:

public class MyClass {
 
 // Won't compile - there is no toStirng method on java.lang.Object.
 @Override
 public String toStirng() {
  return "MyClass toString implementation";
 }
}

Note that @Override can only be used on a method, as only methods can be overridden.

@SuppressWarnings

@SuppressWarnings is an important annotation to be aware of, and unfortunately it hasn't been covered very often. Compilers often emit warnings when they find scenarios in code (with a class, method, field, etc) that are considered bad form or could be the source of problems. Among these are references to @Deprecated elements, unchecked use of a generics-enabled class (e.g. use of a collection without generics), and many others. The comprehensive list for Sun's Java Compiler can be found here in the -Xlint:* sections: http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/javac.html.

Unlike the first two annotations, @SuppressWarnings takes a parameter. Don't worry, though, passing parameters to an annotation isn't hard at all. @SuppressWarnings takes a String[] of warnings to suppress. Here is generally how to suppress some warnings:

@SuppressWarnings({"unchecked", "deprecated"})
public class MyClass { ... }

Note that if you want to suppress only a single type, annotations can 'vararg' a single argument into an array automatically:

@SuppressWarnings("unchecked")
public class MyClass { ... }

What I want to talk about specifically with the warning suppression annotation however is the use of the 'unchecked' flag. This flag is specifically meant for use with generics. In a previous tip ( Generics: Reflecting on Cast-less Reflection ) I discussed how to use type-inference, and there was some discussion about the line that casts and causes a compiler warning. Don't remember? Here is a snippet of the code in question:

// ...
 public <T extends Dao> T getDao(Class<T> type) {
  try {
   Class<? extends Dao> implType = typeMap.get(type);
   // T value = (T)implType.newInstance(); - causes an ugly compiler warning - not the best solution.
   Object valueObj = implType.newInstance();
   T value = type.cast(valueObj); // runtime 'type-safe' cast method
   // configure DAO here
   return value;
  }
  catch(Exception e) {
   throw new RuntimeException("Uh Oh!");
  }
 }
// ...

The cast method was used to hide the fact that compiler was complaining. As best as I know (and all of the readers that responded), there is no way using the current form of generics to support the above algorithm without some form of unsafe runtime-check. While we used the cast method to hide our compiler warning, it is also possible to do this instead:

// ...
 @SuppressWarnings("unchecked")
 public <T extends Dao> T getDao(Class<T> type) {
  try {
   Class<? extends Dao> implType = typeMap.get(type);
   T value = (T)implType.newInstance();
   // configure DAO here
   return value;
  }
  catch(Exception e) {
   throw new RuntimeException("Uh Oh!");
  }
 }
// ...

Which effectively hides the problems we are having due to the shortcomings of generics. As I mentioned in the replies of that tip, since the design ensured that all of the types were determined at compile time (in the constructor of the class), it is a bug of rather small scope (and small likelihood) if the instance returned does not apply to type T .

Stay tuned as I will be covering more annotation details as the week progresses!

1 . At 8:15 AM on Feb 16, 2005, Richard Osbaldeston wrote:
  Click to reply to this thread Reply

Annotations backport for 1.4, 1.3

Has anybody has the chance to use the 175 backport http://backport175.codehaus.org/ stuff yet? just wondering how compatible they are before committing myself to a codebase change (j2se 5.0).

- Richard

thread.rss_message