Java Annotations are a unique kind of Java construct used to associate meta-data with other program features such as class, interface, fields, and methods. Annotations were developed to combat the shortcomings of XML which few architects and application developers found tricky to maintain. Their quest for something that could be closely coupled with code instead of the loosely coupled from code format of XML, gradually gave rise to annotations. Annotations are also credited with bringing standardization to the meta-data definition incode. Prior to annotation, each developer came up with their own ways to define meta-data such as using marker interfaces, comments, transient keywords and the like.
Some features of annotations are:
- They start with @
- They cannot change a compiled program action.
- They should not be confused with pure comments as they can influence the treatment meted out to a program by a compiler.
Following are the 5 annotations supported by all java compiler:
The @Override annotation when used informs the compiler that a method declaration is meant to override a method declaration in the supertype. As Java is an Object-Oriented language with features such as Object- Oriented abstraction mechanisms, any procedure in an interface can be overridden by a subclass. Though this annotation might seem simple- enough, when performed incorrectly can lead to bugs.
Java compiler will show an error for a method annotated with @Override if the following conditions are not met:
- The method implements or overrides a method stated in a supertype
- If the method has a signature which is override-equivalent to any public method stated in Object
There are mainly two advantages to @Override:
- Enhances the readability of the code. In cases where you change the signature of the overridden method, all the subclasses that override that particular method would emit a compilation error which would gradually help you to change the signature of the sub-class. When you change the signature of a method and have many classes in your application, @Override can help you to identify those classes that require change.
- Instances when a programmer makes an error such as wrong parameter types or method name while overriding, they get a compile-time error. By using @Override they can instruct the compiler they are overriding this particular method. If it is not used, the subclass method would act as a new method in a subclass.
This special type of interface has become more common in Java with the advent of lambda expressions in JDK 8. Functional Interfaces can be replaced with lambda expressions, constructor references or method references. Just like the annotation @Override, Java compiler provides the annotation @FunctionalInterface to make certain an interface as a functional interface. Java compiler would send an error if the interface is defined as a non- functional interface and by mistake annotated with the @FunctionalInterface.
Few things to be considered here:
- Abstract classes even if they contain only one abstract method are not functional interfaces
- Functional Interface has only one abstract method. Default methods are not abstract as they have an implementation
Warnings constitute a critical part of any compiler. With warnings, developers get insight into the possible errors or dangerous behavior that can arise in the compiler. Although they are important there are several instances when they are incorrect or cannot be applied. Eg. Warnings may sometimes be emitted for an unsafe type conversion, but it might be safe based on the situation in which it is used.
The annotation @SupressWarnings was introduced in JDK 5 to address this issue: in certain contexts to ignore warnings. There are generally 3 standard warnings in Java language that may be called known by different names depending on compiler implementation. They are
- Unchecked: A warning that indicates an unchecked type cast which can arise due to many reasons including unsafe downcast, unchecked type conversion, access to members of raw types, use of generic parameters with changing arguments and the like.
- Depreciation: It is emitted when depreciated class, method or type is used
- Removal: It is emitted when a terminally depreciated method, class or type is used
@SafeVarags is a very useful tool in Java. However, they can result in grave errors when they are paired with generic arguments. As generic arguments are non- reified in Java, the implementation or the actual kind of variable with a generic type cannot be determined at runtime.
This annotation requires the compiler to apply additional usage restriction other than those enforced by its @Target meta-annotation. A compile-time error is emitted if a method is stated with this annotation and
- The statement is fixed constructor/arity method
- The statement is a variable arity, a method that is not static or fina
There are some instances when developing code, the code becomes outdated and should no longer be used. In these cases, there is usually a better alternative for the task at hand and all new calls should use this method while existing calls to the outdated code may remain. This outdated code is called deprecated code.
Generally, any element annotated with @Deprecated will emit a warning except in the following circumstances:
- When it is used within a declaration that is depreciated
- When it is used within a declaration that is annotated with @SuppressWarnings
- When its declaration and use are within the same outermost class
- When it is used within an import declaration that imports the ordinarily depreciated member/type
- When it is used within an open/exports directive
Each of these annotations has its own unique purpose. They constitute an integral part of Java and will ensure that apps perform the way their developers intended.