Java安全
Java 基础知识
01概述
02变量
03运算符
04程序控制语句
05数组
06面向对象编程
07代码练习
08重载
09作用域
10构造方法&构造器
11this
12包
13修饰符
14封装
15继承
16super
17覆盖&重写
18多态
19零钱通项目
20类变量&类方法
21抽象类
22接口
23内部类
24枚举
25泛型
26常用API
27lambda表达式
28正则表达式
29异常
30File&IO流
31日志技术
32多线程
33网络编程
01反射
02反序列化
03JVM
04JDBC
05RMI
06JRMP
07JNDI
08CDI
09JPA
10Servlet
11Filter
12MVC模型
13MVC框架
14类的加载机制
15Maven
16注解
17ORM
18CC链
19JNDI注入
Log4j2
-
+
首页
16注解
在 Java 中,注解(Annotation) 是一种元数据(Metadata),用于为代码(类、方法、字段等)添加额外信息。它不直接影响代码的执行逻辑,但可以被编译器、工具或运行时环境读取和使用,实现诸如代码检查、自动生成文档、配置映射等功能。注解是 Java SE 5 引入的特性。 ## 基本特性 非执行性:注解本身不包含业务逻辑,仅提供元信息(如 “这个方法是重写的”“这个类需要被 Spring 管理”); 可被解析:需通过注解解析器(如编译器、反射 API、框架中的处理器)读取并处理注解信息,才能发挥作用; 灵活性:可作用于类、方法、字段、参数等不同代码元素,且支持自定义。 ## 语法与定义 ### 注解的使用 使用注解时,需在目标元素(类、方法等)前添加@注解名,例如: ```java // 注解作用于类 @Controller public class UserController { // 注解作用于方法 @GetMapping("/user") public String getUser(@RequestParam String id) { // 注解作用于参数 return "user"; } } ``` ### 自定义注解 通过@interface关键字定义注解,语法类似接口,但本质是特殊的接口(编译后会生成class文件,且隐含继承java.lang.annotation.Annotation)。 示例:定义一个标记 “需要日志记录” 的注解@Log ```java // 元注解:描述注解的行为(见下文) @Target(ElementType.METHOD) // 注解仅能作用于方法 @Retention(RetentionPolicy.RUNTIME) // 注解在运行时保留(可通过反射获取) public @interface Log { // 注解的成员变量(格式:类型 名称() [default 默认值];) String value() default "操作日志"; // 成员变量value,默认值"操作日志" boolean ignore() default false; // 成员变量ignore,默认值false } ``` - 注解的成员变量声明类似方法,但无参数和方法体; - 若成员变量名为value,使用时可省略名称(如@Log("登录操作")等价于@Log(value = "登录操作")); - 无成员变量的注解称为 “标记注解”(如@Override)。 ## 元注解 元注解(Meta Annotation)是专门用于修饰注解的注解,定义了注解的适用范围、保留周期等特性。 | 元注解 | 作用 | 常用参数 | | ----------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | @Target | 指定注解可作用的目标元素类型(如类、方法、字段等)。 | ElementType.TYPE(类 / 接口)、METHOD(方法)、FIELD(字段)、PARAMETER(参数)等。 | | @Retention | 指定注解的保留周期(即注解在哪个阶段有效)。 | RetentionPolicy.SOURCE(仅源码中存在,编译后丢弃);CLASS(编译后保留在 class 文件,运行时丢弃,默认);RUNTIME(运行时保留,可通过反射获取)。 | | @Documented | 标记注解会被javadoc工具提取到文档中(默认注解不包含在文档中)。 | 无参数。 | | @Inherited | 标记注解可被子类继承(即父类的注解会被子类继承)。 | 无参数。 | ## Java 内置注解 Java 提供了 3 个基本注解,用于编译器级别的检查: | 内置注解 | 作用 | 示例 | | ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | @Override | 标记方法是重写父类的方法,编译器会检查是否真的重写(如方法名、参数是否匹配),若不匹配则报错。 | java class Parent { void say() {} } class Child extends Parent { @Override void say() {} // 正确:重写父类方法 } | | @Deprecated | 标记类、方法或字段已过时(不推荐使用),编译器会对使用它们的代码发出警告。 | java @Deprecated class OldClass {} // 使用时编译器会警告 OldClass obj = new OldClass(); | | @SuppressWarnings | 抑制编译器的警告(如未使用变量、 unchecked 转换等),需指定抑制的警告类型。 | java @SuppressWarnings("unused") // 抑制“变量未使用”警告 int a = 10; | ## 注解的解析 注解本身不会生效,需通过解析器处理。解析方式分为两类: ### 编译期解析(源码 / 类文件阶段) 由编译器或 APT(Annotation Processing Tool)工具在编译时解析,用于代码检查或生成额外代码(如 Lombok 的@Data自动生成 getter/setter)。 示例:编译器通过@Override检查方法是否真的重写父类方法,若方法名错误则报错。 ### 运行时解析(反射机制) 通过反射 API 在运行时读取RUNTIME保留策略的注解,动态执行逻辑(这是框架中注解的主要用法)。 示例:解析自定义@Log注解,在方法执行前后打印日志 ```java // 1. 定义@Log注解(保留策略为RUNTIME,见上文) // 2. 使用@Log注解标记方法 public class UserService { @Log(value = "用户登录", ignore = false) public void login(String username) { System.out.println(username + "登录成功"); } } // 3. 反射解析@Log注解 public class LogParser { public static void main(String[] args) throws Exception { // 获取UserService类的login方法 Method method = UserService.class.getMethod("login", String.class); // 检查方法是否有@Log注解 if (method.isAnnotationPresent(Log.class)) { Log logAnnotation = method.getAnnotation(Log.class); // 获取注解的成员变量值 System.out.println("日志描述:" + logAnnotation.value()); System.out.println("是否忽略:" + logAnnotation.ignore()); // 执行方法前打印日志 System.out.println("===== 方法执行前 ====="); // 调用方法 UserService service = new UserService(); service.login("admin"); // 执行方法后打印日志 System.out.println("===== 方法执行后 ====="); } } } // 输出: // 日志描述:用户登录 // 是否忽略:false // ===== 方法执行前 ===== // admin登录成功 // ===== 方法执行后 ===== ```
毛林
2025年10月27日 20:56
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码