The Standard Edition of Java comes with some annotations predefined. You do not need to define them by yourself and you can use them immediately. They allow the compiler to enable some fundamental checking of methods, classes and code.
@Override
This annotation applies to a method and says that this method must override a superclass' method or implement an abstract superclass' method definition. If this annotation is used with any other kind of method, the compiler will throw an error.
Concrete superclass
public class Vehicle {
public void drive() {
System.out.println("I am driving");
}
}
class Car extends Vehicle {
// Fine
@Override
public void drive() {
System.out.prinln("Brrrm, brrm");
}
}
Abstract class
abstract class Animal {
public abstract void makeNoise();
}
class Dog extends Animal {
// Fine
@Override
public void makeNoise() {
System.out.prinln("Woof");
}
}
Does not work
class Logger1 {
public void log(String logString) {
System.out.prinln(logString);
}
}
class Logger2 {
// This will throw compile-time error. Logger2 is not a subclass of Logger1.
// log method is not overriding anything
@Override
public void log(String logString) {
System.out.println("Log 2" + logString);
}
}
The main purpose is to catch mistyping, where you think you are overriding a method, but are actually defining a new one.
class Vehicle {
public void drive() {
System.out.println("I am driving");
}
}
class Car extends Vehicle {
// Compiler error. "dirve" is not the correct method name to override.
@Override
public void dirve() {
System.out.prinln("Brrrm, brrm");
}
}
Note that the meaning of @Override
has changed over time:
(This can occasionally cause problems when back-porting code to Java 5.)
@Deprecated
This marks the method as deprecated. There can be several reasons for this:
the API is flawed and is impractical to fix,
usage of the API is likely to lead to errors,
the API has been superseded by another API,
the API is obsolete,
the API is experimental and is subject to incompatible changes,
or any combination of the above.
The specific reason for deprecation can usually be found in the documentation of the API.
The annotation will cause the compiler to emit an error if you use it. IDEs may also highlight this method somehow as deprecated
class ComplexAlgorithm {
@Deprecated
public void oldSlowUnthreadSafeMethod() {
// stuff here
}
public void quickThreadSafeMethod() {
// client code should use this instead
}
}
@SuppressWarnings
In almost all cases, when the compiler emits a warning, the most appropriate action is to fix the cause. In some instances (Generics code using untype-safe pre-generics code, for example) this may not be possible and it's better to suppress those warnings that you expect and cannot fix, so you can more clearly see unexpected warnings.
This annotation can be applied to a whole class, method or line. It takes the category of warning as a parameter.
@SuppressWarnings("deprecation")
public class RiddledWithWarnings {
// several methods calling deprecated code here
}
@SuppressWarning("finally")
public boolean checkData() {
// method calling return from within finally block
}
It is better to limit the scope of the annotation as much as possible, to prevent unexpected warnings also being suppressed. For example, confining the scope of the annotation to a single-line:
ComplexAlgorithm algorithm = new ComplexAlgorithm();
@SuppressWarnings("deprecation") algoritm.slowUnthreadSafeMethod();
// we marked this method deprecated in an example above
@SuppressWarnings("unsafe") List<Integer> list = getUntypeSafeList();
// old library returns, non-generic List containing only integers
The warnings supported by this annotation may vary from compiler to compiler. Only the unchecked
and deprecation
warnings are specifically mentioned in the JLS. Unrecognized warning types will be ignored.
@SafeVarargs
Because of type erasure, void method(T... t)
will be converted to void method(Object[] t)
meaning that the compiler is not always able to verify that the use of varargs is type-safe. For instance:
private static <T> void generatesVarargsWarning(T... lists) {
There are instances where the use is safe, in which case you can annotate the method with the SafeVarargs
annotation to suppress the warning. This obviously hides the warning if your use is unsafe too.
@FunctionalInterface
This is an optional annotation used to mark a FunctionalInterface. It will cause the compiler to complain if it does not conform to the FunctionalInterface spec (has a single abstract method)
@FunctionalInterface
public interface ITrade {
public boolean check(Trade t);
}
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}