Java注解
注解简介
注解是Java 5引入的一种元数据机制,它提供了一种在代码中添加信息的方式,这些信息可以被编译器、IDE和运行时环境使用。
注解的基本概念
// 内置注解示例
@Override
public String toString() {
return "Hello";
}
@Deprecated
public void oldMethod() {
// 已废弃的方法
}
@SuppressWarnings("unchecked")
public void processList() {
List list = new ArrayList();
// 处理列表
}
注解类型
Java中的注解可以分为三种类型:内置注解、元注解和自定义注解。
// 内置注解
@Override
@Deprecated
@SuppressWarnings
@SafeVarargs
@FunctionalInterface
// 元注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Repeatable
// 自定义注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "";
int count() default 0;
String[] tags() default {};
}
自定义注解
可以通过@interface关键字定义自定义注解,并指定其属性和使用范围。
// 定义注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
String name();
String date();
String[] reviewers() default {};
}
// 使用注解
@Author(
name = "张三",
date = "2024-03-20",
reviewers = {"李四", "王五"}
)
public class MyClass {
@Author(name = "张三", date = "2024-03-20")
public void myMethod() {
// 方法实现
}
}
注解处理
可以通过反射机制在运行时处理注解,或者使用注解处理器在编译时处理注解。
// 运行时处理注解
public class AnnotationProcessor {
public static void processAnnotations(Class> clazz) {
// 获取类上的注解
Author author = clazz.getAnnotation(Author.class);
if (author != null) {
System.out.println("作者:" + author.name());
System.out.println("日期:" + author.date());
System.out.println("审阅者:" + Arrays.toString(author.reviewers()));
}
// 获取方法上的注解
for (Method method : clazz.getMethods()) {
Author methodAuthor = method.getAnnotation(Author.class);
if (methodAuthor != null) {
System.out.println("方法:" + method.getName());
System.out.println("作者:" + methodAuthor.name());
System.out.println("日期:" + methodAuthor.date());
}
}
}
}
常用注解
Java提供了许多内置注解,用于不同的场景。
// 1. 编译时注解
@Override
public void method() {
// 重写父类方法
}
@Deprecated
public void oldMethod() {
// 已废弃的方法
}
@SuppressWarnings("unchecked")
public void processList() {
List list = new ArrayList();
}
// 2. 运行时注解
@Test
public void testMethod() {
// 测试方法
}
@Autowired
private UserService userService;
// 3. 文档注解
/**
* 这是一个示例方法
* @param name 用户名
* @return 欢迎消息
*/
public String welcome(String name) {
return "Welcome, " + name;
}
注解继承
通过@Inherited元注解,可以使注解被子类继承。
// 定义可继承的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface InheritedAnnotation {
String value() default "";
}
// 使用注解
@InheritedAnnotation("父类")
public class Parent {
// 父类内容
}
// 子类继承父类的注解
public class Child extends Parent {
// 子类内容
}
// 验证注解继承
public class InheritanceDemo {
public static void main(String[] args) {
// 获取子类上的注解
InheritedAnnotation annotation = Child.class.getAnnotation(InheritedAnnotation.class);
System.out.println("注解值:" + annotation.value());
}
}
注解组合
可以通过@Repeatable元注解使注解可以重复使用,或者通过注解组合实现更复杂的功能。
// 定义可重复的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Authors.class)
public @interface Author {
String name();
String date();
}
// 定义容器注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Authors {
Author[] value();
}
// 使用重复注解
@Author(name = "张三", date = "2024-03-20")
@Author(name = "李四", date = "2024-03-21")
public class MyClass {
// 类的内容
}
// 处理重复注解
public class RepeatableDemo {
public static void main(String[] args) {
// 获取所有Author注解
Author[] authors = MyClass.class.getAnnotationsByType(Author.class);
for (Author author : authors) {
System.out.println("作者:" + author.name());
System.out.println("日期:" + author.date());
}
}
}
实践练习
练习1:实现一个简单的验证注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Validate {
int min() default 0;
int max() default 100;
String pattern() default "";
}
public class Validator {
public static void validate(Object obj) {
// 实现字段验证逻辑
}
}