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. (sponsored)
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.
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.
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.
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
publicclass SomeClass {
// field
@Deprecated
publicint field;
// constructor
@Deprecated
public SomeClass() {
}
// method
@Deprecated
publicvoid 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:
publicclass 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:
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) {
thrownew 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) {
thrownew 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!
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).
Annotations: Utilizing the Standard Annotations
At 10:44 PM on Feb 15, 2005, R.J. Lorimer wrote:
Fresh Jobs for Developers Post a job opportunity
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@Deprecatedis the complement to the pre-Java-5 '@deprecated' Javadoc tag.@Deprecatedannotations can be applied to any program element for annotations. In the annotation world, that includes all enumeration values in thejava.lang.ElementTypeenumeration (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@Overrideis designed specifically for the compiler to use (later we will learn that this relates to a retention policy of level 'SOURCE'). Use of the@Overridetag 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
@Overridetag 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
@Overridecan only be used on a method, as only methods can be overridden.@SuppressWarnings@SuppressWarningsis 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@Deprecatedelements, 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,
@SuppressWarningstakes a parameter. Don't worry, though, passing parameters to an annotation isn't hard at all.@SuppressWarningstakes 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
castmethod 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 thecastmethod 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 replies so far (
Post your own)
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