Experiences with the New Java 5 Language Featuresby Jess Garms and Tim Hanson12/06/2005 AbstractJava 5.0 is here, and many of you will be starting to use some of the new features added to this release of the JDK. Everything from the enhanced IntroductionDuring the beta period for JDK 1.5, we worked on a Java 5 compiler for BEA's Java IDE. As we implemented various new features, people began exploiting them in new ways; some were clever and some were clearly candidates for a list of what not to do. The compiler itself used the new language features, so we gained direct experience in maintaining code using these features as well. This article is a look at many of these features and our experiences with them. We expect that you are already familiar with the new features, so we don't provide a comprehensive introduction to each. Instead, we'll talk about some of the interesting, hopefully non-obvious implications and uses. These tips are a somewhat random collection of things we ran into, loosely grouped by language feature. We'll start with the simplest features and work our way toward the most advanced ones. Generics is an especially rich subject and therefore occupies about half the article. Enhanced for Loop
The new enhanced Init expressionThe initialization expression is evaluated only once inside the loop. This means that you can often remove a variable declaration. In this example, we had to create an Integer array to hold the results of Without Enhanced For:
int sum = 0;
Integer[] numbers = computeNumbers();
for (int i=0; i < numbers.length ; i++)
sum += numbers[i];
With:
int sum = 0;
for ( int number: computeNumbers() )
sum += number;
LimitationsSometimes you need access to the iterator or index during iteration. Intuitively it seems like the enhanced
for (int i=0; i < numbers.length ; i++) {
if (i != 0) System.out.print(",");
System.out.print(numbers[i]);
}
We want to print out a comma-separated list of the values in the array. We need to know whether we're on the first item in order to know if we should print a comma. With enhanced Here's another example:
for (Iterator<integer> it = n.iterator() ; it.hasNext() ; )
if (it.next() < 0)
it.remove();
In this case, we want to remove the negative items from a collection of Integers. To do this, we need to call a method on the iterator, but when using the enhanced Note, by the way, that AnnotationsAnnotation processing is a large topic. We're not going to cover all the possibilities and pitfalls of it, as we're limiting our article to core language features. We will, however, discuss the built-in annotations (SuppressWarnings, Deprecated, and Override) and limitations of annotation processing in general. Suppress WarningsThis annotation turns off compiler warnings at a class or method level. Sometimes you know better than the compiler that your code must use a deprecated method, or perform some action that cannot be statically determined to be typesafe but in fact is:
@SuppressWarnings("deprecation")
public static void selfDestruct() {
Thread.currentThread().stop();
}
This is probably the most useful of the built-in annotations. Unfortunately, javac doesn't support it as of 1.5.0_04. It is supported in 1.6, however, and Sun is working on back-porting it to 1.5. The annotation is supported in Eclipse 3.1 and possibly other IDEs as well. This allows you to keep your code entirely warning-free. If a warning shows up when compiling, you can be certain that you just added it—helping to keep you aware of possibly unsafe code. With the addition of generics, this is even more desirable. DeprecatedUnfortunately, Deprecated is a little less useful. It's meant to replace the OverrideOverride indicates that the method it annotates should be overriding a method with the same signature in a superclass:
@Override
public int hashCode() {
...
}
Take the above example—if you were to fail to capitalize the "C" in This also helps in the case where the superclass changes. If, say, a new parameter were added to this method and the method itself were renamed, then the subclass will suddenly fail to compile, as it no longer overrides anything in the super. Other annotationsAnnotations can be extremely useful in other situations. They work best for frameworks like EJB and Web services, when behavior is not directly modified, but rather enhanced, especially in the case of adding boilerplate code. Annotations cannot be used as a preprocessor. Sun's design specifically precludes modifying the byte code of a class directly because of an annotation. This is so that the results of the language can be properly understood and tools such as IDEs can perform deep code analysis and functions like refactoring. Annotations are not a silver bullet. When first encountered, people are tempted to try all sorts of tricks. Take this next proposal we got from someone:
public class Foo {
@Property
private int bar;
}
The idea here was to automatically create getter and setter methods for the private field It can't be done because, as we mentioned, Sun specifically precludes modifying the class that an annotation appears in. Even if it were possible, it's not a good idea because it makes this code harder to understand. Someone looking at this code for the first time will have no idea that this annotation creates methods. Also, if in the future you need to do something inside one of those methods, the annotation is useless. In summary, don't try to use annotations to do what regular code can do. |
Article Tools Related Technologies Related Articles Bookmark Article
|