注解
注解概述
注解(Annotation)是Java 5引入的元数据机制,用于在代码中添加信息。
内置注解
java
// @Override - 方法重写
@Override
public String toString() {
return "override method";
}
// @Deprecated - 已过时
@Deprecated
public void oldMethod() {
// 旧方法
}
// @SuppressWarnings - 抑制警告
@SuppressWarnings("unchecked")
public void suppressWarnings() {
List list = new ArrayList();
}
// @FunctionalInterface - 函数式接口
@FunctionalInterface
public interface MyFunction {
void apply();
}元注解
元注解用于定义注解的注解。
@Target
指定注解可以应用的位置:
java
@Target(ElementType.TYPE) // 类、接口、枚举
@Target(ElementType.FIELD) // 字段
@Target(ElementType.METHOD) // 方法
@Target(ElementType.PARAMETER) // 参数
@Target(ElementType.CONSTRUCTOR) // 构造方法
@Target(ElementType.LOCAL_VARIABLE) // 局部变量
@Target(ElementType.ANNOTATION_TYPE) // 注解类型
@Target(ElementType.PACKAGE) // 包
@Target(ElementType.TYPE_USE) // 类型使用(Java 8+)
@Target(ElementType.TYPE_PARAMETER) // 类型参数(Java 8+)
// 多个位置
@Target({ElementType.TYPE, ElementType.METHOD})@Retention
指定注解的保留策略:
java
@Retention(RetentionPolicy.SOURCE) // 源码保留,编译时丢弃
@Retention(RetentionPolicy.CLASS) // 字节码保留,默认值
@Retention(RetentionPolicy.RUNTIME) // 运行时保留,可通过反射获取@Documented
指定注解是否包含在JavaDoc中:
java
@Documented
public @interface MyAnnotation {
}@Inherited
指定注解是否被子类继承:
java
@Inherited
public @interface MyAnnotation {
}@Repeatable
指定注解是否可重复使用(Java 8+):
java
@Repeatable(Authors.class)
public @interface Author {
String name();
}
public @interface Authors {
Author[] value();
}
// 使用
@Author(name = "张三")
@Author(name = "李四")
public class Book {
}自定义注解
基本定义
java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "";
int count() default 0;
String[] tags() default {};
}使用自定义注解
java
public class AnnotationDemo {
@MyAnnotation(value = "test", count = 10, tags = {"a", "b"})
public void method() {
}
// value可以省略名称
@MyAnnotation("simple")
public void simpleMethod() {
}
}注解属性类型
java
public @interface Types {
// 基本类型
int intValue();
long longValue();
double doubleValue();
boolean booleanValue();
// String
String stringValue();
// Class
Class<?> classValue();
// 枚举
ElementType enumValue();
// 注解
Deprecated annotationValue();
// 数组
String[] arrayValue();
// 默认值
String name() default "default";
}注解处理器
运行时处理
java
import java.lang.reflect.Method;
public class AnnotationProcessor {
public static void process(Class<?> clazz) {
// 检查类上的注解
if (clazz.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
System.out.println("类注解: " + annotation.value());
}
// 检查方法上的注解
for (Method method : clazz.getDeclaredMethods()) {
if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
System.out.println("方法 " + method.getName() +
" 注解: " + annotation.value());
}
}
}
}实战示例:简易ORM
java
import java.lang.annotation.*;
import java.lang.reflect.Field;
// 表名注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String name();
}
// 列名注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String name();
String type() default "VARCHAR(255)";
}
// 实体类
@Table(name = "users")
public class User {
@Column(name = "id", type = "INT PRIMARY KEY")
private int id;
@Column(name = "username")
private String username;
@Column(name = "email")
private String email;
// getters and setters
}
// SQL生成器
public class SqlGenerator {
public static String createTable(Class<?> clazz) {
StringBuilder sql = new StringBuilder("CREATE TABLE ");
Table table = clazz.getAnnotation(Table.class);
if (table == null) {
throw new RuntimeException("No Table annotation");
}
sql.append(table.name()).append(" (\n");
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
Column column = field.getAnnotation(Column.class);
if (column != null) {
sql.append(" ").append(column.name())
.append(" ").append(column.type());
if (i < fields.length - 1) {
sql.append(",");
}
sql.append("\n");
}
}
sql.append(")");
return sql.toString();
}
public static void main(String[] args) {
System.out.println(createTable(User.class));
}
}实战示例:方法日志
java
import java.lang.annotation.*;
import java.lang.reflect.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
}
public class LogHandler implements InvocationHandler {
private Object target;
public LogHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Log log = method.getAnnotation(Log.class);
if (log != null) {
System.out.println("执行方法: " + method.getName() +
", 日志: " + log.value());
}
return method.invoke(target, args);
}
@SuppressWarnings("unchecked")
public static <T> T createProxy(T target) {
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new LogHandler(target)
);
}
}
// 使用
interface UserService {
@Log("查询用户")
void getUser(int id);
@Log("保存用户")
void saveUser(String name);
}
public class UserServiceImpl implements UserService {
@Override
public void getUser(int id) {
System.out.println("获取用户: " + id);
}
@Override
public void saveUser(String name) {
System.out.println("保存用户: " + name);
}
}
// 测试
UserService service = LogHandler.createProxy(new UserServiceImpl());
service.getUser(1);
service.saveUser("张三");常用框架注解
Spring注解
java
@Component // 组件
@Service // 服务层
@Repository // 数据访问层
@Controller // 控制器
@Autowired // 自动注入
@Qualifier // 指定注入Bean
@Value // 注入配置值
@Configuration // 配置类
@Bean // Bean定义
@Scope // 作用域
@Transactional // 事务
@RequestMapping // 请求映射
@GetMapping // GET请求
@PostMapping // POST请求JPA注解
java
@Entity // 实体类
@Table // 表名
@Id // 主键
@GeneratedValue // 自动生成
@Column // 列定义
@OneToMany // 一对多
@ManyToOne // 多对一
@ManyToMany // 多对多Jackson注解
java
@JsonProperty // 属性名映射
@JsonIgnore // 忽略属性
@JsonFormat // 日期格式
@JsonInclude // 包含策略
@JsonPropertyOrder // 属性顺序