1. Overview
Let’s dive deep to see what interface and @interface are and their applications. An interface is a contract for a class that implements it. In the most common form, it is a group of related methods with empty bodies.
On the other hand, an @interface allows you to add metadata to your code. The compiler, tools, or framework uses this metadata to influence class behavior or processing.
2. interface
An interface acts like a contract for its implementing class. It specifies a behavior that its implementing classes must implement without dictating how. It suggests that any class implementing the interface must provide concrete implementations for all its methods.
public interface Animal {
String eat();
String sleep();
}
public class Dog implements Animal {
@Override
public String eat() {
return "Dog is eating";
}
@Override
public String sleep() {
return "Dog is sleeping";
}
}
All interface methods are implicitly public and abstract (except default and static methods), and all fields are public, static, and final. We can achieve abstraction, multiple inheritances, and loose coupling in Java using interfaces.
Abstraction: The interface reveals only the essential information needed to invoke the method, whereas the complexities of the implementation remain concealed.
Multiple Inheritance: A class can implement several interfaces, thereby avoiding the diamond problem that can arise in languages that allow multiple inheritance from classes.
Loose Coupling: Interfaces provide a distinct separation between the functionality and the implementation details. It enables a class to alter its internal processes without affecting its users, as we define the method and the signature separately.
3. @interface
In Java, we use @interface to declare an annotation type. Annotations provide a way to add metadata to Java code elements like classes, methods, and fields. Consequently, tools and libraries can leverage this metadata to gather information during the compilation process or the runtime for code processing.
Let’s create an @Review custom annotation, which we can use to track who reviewed a piece of code and when:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Review {
String reviewer();
String date() default "";
}
Notice that when defining the Review annotation using @interface, we define it as a regular interface. We have method names and return types that use primitive data types or even arrays. However, we cannot use complex objects for return types.
Also, we need to provide values for all the above-defined properties while using our Review annotation. There is a way to define a default value at the time of declaration. We can use it if we don’t always need the value provided while using the annotation.
Also, one more thing to notice is the @Retention and the @Target annotations above the @interface definition. The @Retention(RetentionPolicy.SOURCE) annotation makes our annotation available in the source code. The @Target({ElementType.METHOD}) annotation specifies that the Review annotation will be applied only to the methods in a Java class.
Now, let’s use the @Review annotation in the service method:
@Review(reviewer = "Natasha", date = "2024-08-24")
public String service() {
return "Some logic here";
}
4. Comparison
Aspect
interface
@interface
Purpose
Used to define a contract that classes can implement.
Used to define a custom annotation.
Contains
Method signatures without implementations, default methods, static methods, and constants.
Annotation methods that provide metadata.
@Retention: Specifies retention of annotations.
@Target: Specifies the program elements to which an annotation type is applicable.
Usage
Implemented by classes to provide specific behavior.
Used to annotate code elements (classes, methods, fields, etc.) to provide metadata.
Use Cases
To achieve abstraction, multiple inheritance in Java and decoupling methods from its implementations.
To define custom annotation that can provide metadata for frameworks that support code documentation, configuration, code generation, and validations.
5. Conclusion
Understanding the distinction between interface and @interface is crucial as they play different roles in Java programming. An interface is about defining types and contracts. @interface is about providing metadata to the compiler or the runtime.
The complete source code for the above examples is available over on GitHub.