Preface
In Java,@
Symbols are used to represent annotation. Annotations are a feature introduced in Java 5.0, which provides a safe way to add metadata to program elements (classes, methods, variables, etc.). Annotations themselves do not directly affect the logic of the program, but they can be used by compilers, tools, or runtime environments to process code to achieve specific functions.
Annotations are usually used in the following aspects:
-
Compile-time check: Certain annotations can help the compiler verify the correctness of the code, such as
@Override
Annotations can ensure that the method you override does exist in the parent class. - Compile-time processing: Some annotations can be processed at compile time, generating additional source files or modifying bytecode, such as using an annotation processor to automatically generate code.
-
Runtime processing: Some annotations can be read through reflection mechanism at runtime and perform specific logic based on this, such as the Spring framework
@Autowired
Annotations are used for automatic assembly dependencies. -
Document generation: Annotations can also be used to generate documents, such as
@Deprecated
Annotation means that a program element is outdated and should not be used again.
Common built-in annotations include:
-
@Override
: Used to mark the case of overriding method. -
@Deprecated
: Tags a deprecated method or class. -
@SuppressWarnings
: Used to suppress compiler warnings.
Custom annotations can be passed@interface
Keywords are created, and custom annotations can be accompanied by members that provide the necessary information when using annotations.
Example:
public @interface MyAnnotation { String value() default "default value"; } @MyAnnotation(value = "Hello, World!") public class MyClass { // Class content}
In this example,MyAnnotation
is a custom annotation, it has a name calledvalue
The default value of"default value"
。MyClass
This annotation is applied on the class and specifiedvalue
The specific value of the member.
1. Definition annotation
Annotations are essentially an interface, but they are declared differently from normal interfaces. Definition annotation use@interface
Keywords. Annotations can have members, which are similar to interface methods, but have some limitations, such as member types can only be primitive types, strings, classes, enums, annotations, or arrays of the above types.
Example: Define a simple annotation
public @interface MyAnnotation { String value() default ""; // The default value is an empty string int count() default 1; // The default value is 1}
2. Meta-annotation of annotation
Meta-annotations are annotations used to modify annotations. Java provides some standard meta annotations:
-
@Retention
: Specify the retention policy of the annotation. -
@Target
: Specifies the target type that annotations can apply. -
@Documented
: Specifies whether annotations should be included in JavaDoc. -
@Inherited
: Specifies whether annotations can be inherited by subclasses.
Example: Using meta annotations
import ; import ; import ; import ; @Retention() // Annotations are preserved at runtime@Target() // Annotations can be applied to methodspublic @interface MyAnnotation { String value() default ""; int count() default 1; }
3. Annotation retention strategy
@Retention
Meta-annotations are used to specify the retention strategy of annotations, that is, at which stage the annotations are valid. There are three main retention strategies:
-
: Annotations are only retained at the source code level and will be ignored during compilation.
-
: The annotation remains in the class file but is not loaded into the JVM.
-
: The annotation is retained in the JVM and can be obtained by reflection at runtime.
4. Application objectives of annotations
@Target
Meta-annotations are used to specify the target type that annotations can apply. Common target types include:
-
: Class, interface (including annotation types) or enumeration declaration.
-
: Fields, enumeration constants.
-
:method.
-
:parameter.
-
:Construction method.
-
ElementType.LOCAL_VARIABLE
: Local variables. -
ElementType.ANNOTATION_TYPE
: Annotation type. -
: Package statement.
5. Runtime processing annotations
Processing annotations at runtime usually requires the use of reflection mechanisms. Through reflection, you can obtain annotations on classes, methods, fields, etc., and read the member values of the annotations.
Example: Runtime processing annotations
import ; import ; import ; import ; @Retention() @Target() public @interface MyAnnotation { String value() default ""; int count() default 1; } public class MyClass { @MyAnnotation(value = "Hello", count = 5) public void myMethod() { ("This is my method."); } } public class Main { public static void main(String[] args) throws Exception { Method method = ("myMethod"); if (()) { MyAnnotation annotation = (); ("Value: " + ()); ("Count: " + ()); } } }
6. Built-in annotations
Java provides some built-in annotations for common programming scenarios:
-
@Override
: indicates method coverage. -
@Deprecated
: means that the method or class has been deprecated. -
@SuppressWarnings
: Used to suppress compiler warnings.
7. Custom annotation processor
Annotation processor is a tool that processes annotations at compile time. With the annotation processor, additional source code can be generated at compile time or other operations can be performed. Java providesPackage to support the development of annotation processor.
Example: Defining a simple annotation processor
import ; import ; import ; import ; import ; import ; import ; import ; import ; @SupportedAnnotationTypes("") @SupportedSourceVersion(SourceVersion.RELEASE_8) public class MyAnnotationProcessor extends AbstractProcessor { @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { for (TypeElement annotation : annotations) { Set<? extends Element> annotatedElements = (annotation); for (Element element : annotatedElements) { try (PrintWriter out = new PrintWriter(().createSourceFile(() + "Generated").openWriter())) { ("public class " + () + "Generated {"); (" public void generatedMethod() {"); (" (\"This is a generated method.\");"); (" }"); ("}"); } catch (IOException e) { (); } } } return true; } }
8. Application scenarios of annotation
Annotations are very common in modern Java development, especially in frameworks and libraries. Here are some typical application scenarios:
-
Dependency injection: Such as in the Spring framework
@Autowired
。 -
Unit Testing: Like in JUnit
@Test
。 -
Web Framework: Such as in Spring MVC
@RequestMapping
。 -
Persistence framework: Like in Hibernate
@Entity
and@Table
。 -
Configuration Management: Like in Spring Boot
@Configuration
and@Bean
. sure! We continue to explore the advanced features and application scenarios of Java annotations in depth.
9. Combination of annotations
In actual development, annotations are often used in combination to achieve more complex functions. For example, the Spring framework@RestController
It is actually a combination annotation, which contains@Controller
and@ResponseBody
。
Example: Define a combination annotation
import ; import ; import ; import ; @Retention() @Target() public @interface MyCustomController { @MyAnnotation Class<?> value(); } @Retention() @Target() public @interface MyAnnotation { String value() default ""; } @MyCustomController(value = ) public class MyClass { // Class content}
10. Default value of annotation
Members of annotations can have default values, which allows explicit assignments of these members to be omitted when using annotations.
Example: Annotation with default values
@Retention() @Target() public @interface MyAnnotation { String value() default "default value"; int count() default 1; } public class MyClass { @MyAnnotation public void myMethod() { ("This is my method."); } }
11. Repeat comments
Starting from Java 8, the concept of repeated annotations has been introduced. Allows the same annotation to be used multiple times in one place.
Example: Defining and using duplicate annotations
import ; import ; import ; import ; @Retention() @Target() public @interface MyAnnotations { MyAnnotation[] value(); } @Repeatable() @Retention() @Target() public @interface MyAnnotation { String value() default ""; } public class MyClass { @MyAnnotation(value = "First") @MyAnnotation(value = "Second") public void myMethod() { ("This is my method."); } } public class Main { public static void main(String[] args) throws Exception { Method method = ("myMethod"); if (()) { MyAnnotations annotations = (); for (MyAnnotation annotation : ()) { ("Value: " + ()); } } else if (()) { MyAnnotation annotation = (); ("Value: " + ()); } } }
12. Inheritance of annotations
Although the annotation itself cannot be inherited, it can be passed@Inherited
Meta-annotation makes the annotation inheritable. This means that if a class uses an annotation, its subclasses will also inherit the annotation.
Example: Use @Inherited MetaAnnotation
import ; import ; import ; import ; @Inherited @Retention() @Target() public @interface MyAnnotation { String value() default ""; } @MyAnnotation(value = "Parent") public class ParentClass { // Class content} public class ChildClass extends ParentClass { // Class content} public class Main { public static void main(String[] args) { Class<?> clazz = ; if (()) { MyAnnotation annotation = (); ("Value: " + ()); } } }
13. Application of annotations in the framework
Annotations are widely used in many popular Java frameworks, and the following are some typical application scenarios:
- Spring Framework:
-
@Autowired
: Automatically inject dependencies. -
@Controller
/@RestController
: Identify the controller class. -
@Service
: Identify the service layer class. -
@Repository
: Identify the data access layer class. -
@Transactional
: Manage transactions.
-
- Hibernate:
-
@Entity
: Identify the entity class. -
@Table
: Specify the table name. -
@Column
: Specify the column name. -
@Id
: Identify the primary key.
-
- JUnit:
-
@Test
: Identify the test method. -
@Before
/@After
: Identifies the method executed before/after each test method. -
@BeforeClass
/@AfterClass
: Identifies the method executed before/after all test methods.
-
- Servlet 3.0+:
-
@WebServlet
: Identify the Servlet. -
@WebFilter
: Identify the filter. -
@WebListener
: Identify the listener.
-
14. Performance impact of annotations
Annotations themselves do not have a significant impact on the performance of the program, because they are just metadata. However, if reflection is frequently used to process annotations at runtime, it may have some impact on performance. Therefore, the frequency of the annotation usage and performance requirements should be weighed during design.
15. Best Practices
- Concise and clear: The annotations should be concise and clear to avoid overly complex logic.
- Reasonable use: Annotations should not replace traditional programming logic, but should be used as an auxiliary means.
- Documentation: The use of annotations should be well documented so that other developers can understand their purpose.
- Performance considerations: Avoid frequent use of reflection to handle annotations in performance-sensitive code paths.
Best practices for java annotation
Java annotations are very flexible, but to ensure the maintainability and performance of your code, it is important to follow some best practices. Here are some best practices on how to use Java annotations effectively:
1. Keep the annotations simple and clear
- Simplicity: The annotation should be as concise as possible to avoid too many members and complex logic.
- Clearly named: The annotation name should be clear and meaningful, and it can tell its purpose at a glance.
2. Use meta annotations
-
Retention strategy:use
@Retention
Specify the retention policy of the annotation. Normally, if the annotation is only used for compile-time checking, you can chooseSOURCE
;If you need to process annotations at runtime, selectRUNTIME
。 -
Target Type:use
@Target
Specify the target type that annotations can be applied to ensure that the annotations are used in the appropriate context. -
Documentation:use
@Documented
Include annotations in the generated JavaDoc to improve the readability and maintainability of the code. -
Inheritance:use
@Inherited
Make the annotation inheritable and suitable for scenarios where subclasses need to inherit the parent class annotation.
3. Avoid overuse of annotations
- Moderate use: Annotations should not replace traditional programming logic, but serve as auxiliary means. Overuse of annotations can increase the complexity of the code and maintenance difficulty.
- Avoid redundancy: Do not reuse the same annotations without need to avoid redundancy and confusion.
4. Use default values
- default value: Provide reasonable default values for annotation members, so that unnecessary parameters can be omitted when using annotations, making the code more concise.
5. Documented annotations
- Comments: Add detailed comments to annotations and their members to explain their uses and usage methods.
- Example: Provide examples of annotation usage to help other developers understand how to use annotations correctly.
6. Performance considerations
- Reflection use: Avoid frequent use of reflection to handle annotations in performance-sensitive code paths. You can consider cache the processing results of the annotation to reduce duplicate reflective calls.
- Compile-time processing: If possible, use the annotation processor to process the annotation at compile time, generate additional source code or perform other optimizations.
7. Combination annotation
- Combination use: Use combination annotations reasonably, combine multiple related annotations into one, and simplify the use of annotations.
- consistency: Ensure the consistency and semantic clarity of combined annotations to avoid confusion.
8. Test annotations
- Unit Testing: Write unit tests to verify the behavior and effectiveness of annotations to ensure that the annotations work as expected.
- Integration Testing: Verify the performance of annotations in actual applications in integration tests to ensure there are no omissions or errors.
9. Follow the best practices of the framework
- Framework Specifications: Follow best practices and recommended usage of the framework when using the annotations provided by the framework.
- Extensibility: If you need to extend the framework functionality, consider using custom annotation and annotation processor.
10. Code review
- Code review: Pay special attention to the use of annotations during the code review process to ensure the correctness and rationality of the annotations.
- Team consensus: Arriving a consensus with team members to unify the usage specifications and styles of annotations.
Example: Definition and use of annotations that follow best practices
import ; import ; import ; import ; import ; import ; // Define an annotation@Documented @Inherited @Retention() @Target() public @interface MyAnnotation { String value() default "default value"; int count() default 1; } // Use annotationpublic class MyClass { @MyAnnotation(value = "Hello", count = 5) public void myMethod() { ("This is my method."); } } // Process the annotationpublic class Main { public static void main(String[] args) throws Exception { Method method = ("myMethod"); if (()) { MyAnnotation annotation = (); ("Value: " + ()); ("Count: " + ()); } } }
Summarize
This is the article about the role and usage of symbol @ in java. For more relevant java symbol @ usage content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!