Java注解案例如何基础使用

wen java案例 24

Java注解案例:基础使用全解析,从零搭建高效编程利器

目录导读

  • 什么是Java注解?核心概念速览
  • 注解的分类与生命周期
  • 基础案例1:自定义注解的声明与使用
  • 基础案例2:结合反射解析运行时注解
  • 基础案例3:内置注解实战(@Override、@Deprecated、@SuppressWarnings)
  • 常见问答:注解原理与最佳实践
  • 让注解成为你的代码“标签系统”

什么是Java注解?核心概念速览

Java注解(Annotation)是一种元数据机制,允许开发者在代码中添加结构化的标记信息,这些信息可以被编译器、工具或运行时环境读取并执行相应行为,本质上,注解是一种“代码级别的注释”,但比普通注释更强大——它不仅记录说明,还能驱动程序逻辑。

Java注解案例如何基础使用

注解的三大核心作用:

  1. 编译检查:如@Override强制检查方法重写是否正确。
  2. 代码生成:如Lombok的@Getter自动生成getter方法。
  3. 运行时处理:如Spring框架的@Autowired实现依赖注入。

问:注解和注释有什么区别?
答:注释(、)仅供人类阅读,编译后消失;注解(@XXX)可被程序读取并处理,是提供给JVM或框架的“指令”。


注解的分类与生命周期

Java注解按保留策略分为三类,通过@Retention控制:

类型 保留策略 使用场景
源代码注解 RetentionPolicy.SOURCE 仅源码阶段,编译器丢弃(如@Override
编译时注解 RetentionPolicy.CLASS 编译时保留,JVM不可见(如Lombok的注解)
运行时注解 RetentionPolicy.RUNTIME 运行时保留,可通过反射读取(如Spring的@Component

元注解:用于修饰其他注解的注解,包括:

  • @Target:限定注解可用位置(方法、字段、类等)
  • @Retention:生命周期策略
  • @Documented:是否加入Javadoc
  • @Inherited:是否被子类继承

基础案例1:自定义注解的声明与使用

步骤1:定义注解

import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)  // 运行时保留,可用反射
@Target(ElementType.METHOD)          // 只能应用于方法
public @interface UserAction {
    String value() default "defaultAction";  // 注解属性,支持默认值
    int priority() default 1;
}

步骤2:使用注解

public class UserService {
    @UserAction(value = "login", priority = 5)
    public void login() {
        System.out.println("用户登录");
    }
    @UserAction("logout")  // 只有value时可直接写值
    public void logout() {
        System.out.println("用户登出");
    }
}

问:注解属性为什么像方法声明?
答:注解的属性通过方法定义,使用时代入参数,本质是编译器处理成特殊接口,运行时通过反射调用方法获得值。


基础案例2:结合反射解析运行时注解

这是注解最强大的用法——通过反射读取标记信息并动态执行操作。

import java.lang.reflect.Method;
public class ActionParser {
    public static void parseUserActions(Object obj) {
        Class<?> clazz = obj.getClass();
        for (Method method : clazz.getDeclaredMethods()) {
            if (method.isAnnotationPresent(UserAction.class)) {
                UserAction action = method.getAnnotation(UserAction.class);
                System.out.println("发现业务方法:" + method.getName());
                System.out.println("动作描述:" + action.value());
                System.out.println("优先级:" + action.priority());
                // 动态调用方法(模拟权限校验)
                System.out.println("--- 开始执行权限检查 ---");
                try {
                    method.invoke(obj);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) {
        ActionParser.parseUserActions(new UserService());
    }
}

输出示例

发现业务方法:login
动作描述:login
优先级:5
--- 开始执行权限检查 ---
用户登录
发现业务方法:logout
动作描述:logout
优先级:1
--- 开始执行权限检查 ---
用户登出

关键代码解释:

  • isAnnotationPresent():检查方法是否有指定注解
  • getAnnotation():获取注解实例,读取属性值
  • method.invoke():通过反射执行业务逻辑

基础案例3:内置注解实战

@Override —— 强制重写检查

class Parent {
    public void sayHello() {
        System.out.println("Parent hello");
    }
}
class Child extends Parent {
    @Override  // 若方法签名写错(如sayHello拼成sayhelo),编译报错
    public void sayHello() {
        System.out.println("Child hello");
    }
}

@Deprecated —— 标记过时方法

public class LegacyApi {
    @Deprecated  // 调用时会出现删除线警告
    public void oldMethod() {
        System.out.println("此方法已过时,推荐使用newMethod");
    }
    public void newMethod() {
        System.out.println("推荐新方法");
    }
}

@SuppressWarnings —— 压制编译警告

@SuppressWarnings({"unchecked", "rawtypes"})
public void processList() {
    List list = new ArrayList();  // 原始类型警告被压制
    list.add("数据");
}

问:为什么生产代码要慎用@SuppressWarnings?
答:它隐藏了潜在的类型不安全代码,最佳实践是优先修复警告,仅在第三方API兼容等少数场景下使用。


常见问答:注解原理与最佳实践

Q1: 注解能否被继承?

  • 默认不继承,若A类有注解@X,B继承A,则B类无@X。
  • 需在@X上加上@Inherited元注解,才可被子类继承(仅适用于类级别)。

Q2: 百万级调用下,注解反射有性能损耗吗?

  • 有,尤其涉及getDeclaredMethods()getAnnotation(),优化方案:
    • 缓存解析结果到Map中(单例模式)
    • 使用编译时注解处理(APT技术,如Lombok的注解处理器)

Q3: 如何选择SOURCE、CLASS、RUNTIME?

  • 纯编译检查(如@NonNull):用SOURCE
  • 编译时代码生成(如Lombok):用CLASS
  • 运行时框架读取(如Spring、Hibernate):必用RUNTIME

让注解成为你的代码“标签系统”

通过本文的三个案例,你应该已经掌握了Java注解的基础使用技能:

  1. 自定义注解:用@interface定义,配合元注解控制生命期和目标
  2. 运行时解析:反射API读取注解信息,实现动态逻辑
  3. 内置注解:善用@Override@Deprecated提升代码质量

核心心法:注解的本质是“元数据”,它让代码具备自描述能力,为框架(Spring、MyBatis)和工具(Lombok、JUnit)提供扩展点,建议从简单场景开始运用,比如用注解标记权限级别、接口版本等,逐步体会其“非侵入式增强”的魅力。


(本文所有代码已验证可在JDK 8+环境运行,建议在IDE中手动输入练习效果更佳。)

抱歉,评论功能暂时关闭!