JavaSE : 注解 Annotation

注解

Java中的注解(Annotation)是一种元数据形式,用于向编译器或JVM提供有关程序元素(如类、方法、变量、参数和包)的附加信息。注解不会直接影响程序的行为或结构,但它们可以被编译器、开发工具或运行时环境用于生成代码、进行验证、执行处理或提供信息。以下是关于Java注解的几个关键点:

1. 注解的种类

1.1.内置标准注解

  • @Override:指示一个方法覆盖了超类中的方法。
  • @Deprecated:标记已过时的元素,建议不再使用。
  • @SuppressWarnings:抑制编译器警告。

1.2.元注解:给注解用的注解

用于创建自定义注解的注解,包括:

1.2.1.@Retention

指定注解保留策略(解析时间),如RetentionPolicy.SOURCE(只保留在源码中)、RetentionPolicy.CLASS(保留在class文件中)或RetentionPolicy.RUNTIME(运行时可通过反射访问)。

1.2.1.1. SOURCE : 编译时(Compile Time)

编译时解析的注解在源代码被编译成字节码时被处理。这些注解主要用于生成额外的代码、检查代码的正确性或进行其他静态分析。例如,@Override, @Deprecated, 和一些编译器使用的注解如Lombok的@Data就是在编译时期被解析的。编译器或注解处理器(如APT, Annotation Processing Tool)会读取这些注解并据此执行相应的操作。

1.2.1.2.CLASS : 类加载时(Class Load Time)

这类注解在类被加载到Java虚拟机(JVM)时被解析。例如,一些框架或库会在类加载阶段利用这些注解来配置类的行为,如Spring框架使用@Component, @Service, @Autowired等注解来实现依赖注入和bean的装配,这些注解会在应用上下文初始化,即类加载时被解析和处理。

1.2.1.3.RUNTIME : 运行时(Runtime)

运行时解析的注解在应用程序运行过程中可以被读取和处理。这意味着注解信息在程序执行期间始终可用,可以通过反射API来访问这些注解。例如,@Retention(RetentionPolicy.RUNTIME)注解的那些注解可以在程序运行时通过反射被检测到,常用于自定义注解处理、日志记录、权限控制等场景。

1.2.2.@Target

指定注解可以应用到哪些程序元素上。

它接受一个ElementType类型的枚举值数组作为参数,ElementType枚举定义了一系列可能的目标元素类型。以下是ElementType的一些主要选项:

  1. ElementType.TYPE: 类、接口(包括注解类型)或枚举声明。
  2. ElementType.FIELD: 类或接口中的字段声明(包括枚举常量)。
  3. ElementType.METHOD: 类或接口中的方法声明。
  4. ElementType.PARAMETER: 方法参数声明。
  5. ElementType.CONSTRUCTOR: 类的构造函数声明。
  6. ElementType.LOCAL_VARIABLE: 本地变量声明。
  7. ElementType.ANNOTATION_TYPE: 另一个注解的声明。
  8. ElementType.PACKAGE: 包声明。
  9. ElementType.TYPE_PARAMETER: 类型参数声明(Java 8及以后版本)。
  10. ElementType.TYPE_USE: 任何类型使用的地方,如泛型参数、类型转换、静态成员的类型等(Java 8及以后版本)。

1.2.3.@Documented

指示该注解应被包含在生成的API文档中。

1.2.4.@Inherited

允许子类继承父类上的注解。

1.2.5.@Repeatable

自Java 8起,允许同一注解在同一声明上多次使用。

1.3.自定义注解

开发者可以定义自己的注解,通过@interface关键字实现,用于满足特定的编程需求或框架集成。

public @interface MyAnnotation {

}

1.3.1.注解的参数

定义注解参数

  1. 参数类型:注解参数必须是基本类型、String、Class、枚举类型、注解类型或者这些类型的数组。不能使用其他复杂类型如自定义类作为参数。

  2. 默认值:每个注解参数都可以有一个默认值,如果没有提供默认值且该参数又是必需的,则在使用注解时必须显式指定参数值。

  3. 参数命名:参数命名遵循Java的标识符规则,通常采用小驼峰命名法。

示例定义

public @interface MyAnnotation {
    String name() default "";      // 默认值为空字符串
    int age();                    // 必须提供值,没有默认值
    Class<?> clazz() default Object.class; // 默认值为Object类
    ElementType[] targets();       // 参数可以是数组类型
}

使用注解参数

在应用注解时,通过参数名指定参数值,如果是数组类型的参数,可以使用花括号 {} 来包裹多个值。

@MyAnnotation(name = "Alice", age = 25, clazz = String.class, targets = {ElementType.FIELD, ElementType.METHOD})
public class MyClass {
    // ...
}

特殊参数类型

  • Class类型参数:允许指定一个类或接口类型。
  • 枚举类型参数:限制参数为预定义的一组值。
  • 注解类型参数:允许注解作为参数,用于嵌套注解的情况。
  • 数组类型参数:支持传递多个相同类型的值,如上面的targets参数。

1.3.2.value参数

在Java注解中,value是一个特殊的参数名。当一个注解只有一个参数,并且该参数名为value时,你可以省略参数名直接指定值。这种设计让注解的使用更加简洁易读。下面是具体说明和示例:

特殊之处

  • 默认识别:如果一个注解仅定义了一个参数,并且这个参数的名字是value,那么在使用该注解时,可以直接写值而不必指定参数名。编译器会自动将这个值赋给value参数。
  • 多参数注解中的value : 即使一个注解定义了多个参数,如果其中包含名为value的参数,你仍然可以在只有一个值需要传递时省略value=。但是,如果有多个值需要指定,则所有参数都必须明确指出参数名。

示例定义

public @interface MySingleValueAnnotation {
    String value(); // 注意这里只有一个名为value的参数
}

使用示例

@MySingleValueAnnotation("Some text") // 直接写值,不需要写value=
public class MyClass {
    // ...
}

// 对于非字符串或基本类型,同样适用
@MySingleValueAnnotation(123) // 假设value参数类型为int
public void myMethod() {
    // ...
}

2.访问注解信息

在Java中,通过反射处理注解是一种常见的做法,主要用于在运行时 ( 即使用@Retention(RUNTIME)定义的注解 ) 动态地检查和操作那些被注解标记的类、方法、字段等元素。以下是一些基本步骤和示例,展示如何使用反射来获取和使用注解信息:

2.1. 获取注解实例

首先,你需要获取到你想要检查的类、方法或字段的 Class 对象。之后,可以使用这个 Class 对象提供的几个方法来检查和获取注解:

  • isAnnotationPresent(Class<? extends Annotation> annotationClass):检查是否具有指定类型的注解。
  • getAnnotation(Class<? extends Annotation> annotationClass):获取指定类型的注解实例,如果没有则返回 null
  • getAnnotations()getDeclaredAnnotations():获取所有注解或直接声明的注解数组。

示例:获取类上的注解

假设我们有一个自定义的注解 @MyAnnotation,并应用到了某个类 MyClass 上。

@MyAnnotation(value = "Hello, World!")
public class MyClass {
    // ...
}

获取这个类上的 MyAnnotation 实例:

Class<MyClass> clazz = MyClass.class;
if (clazz.isAnnotationPresent(MyAnnotation.class)) {
    MyAnnotation myAnnotation = clazz.getAnnotation(MyAnnotation.class);
    System.out.println("注解的值: " + myAnnotation.value());
}

示例:获取方法上的注解

同样的,如果 MyAnnotation 应用于某个方法上:

public class MyClass {
    @MyAnnotation(value = "Method Annotation")
    public void myMethod() {
        // ...
    }
}

获取方法上的注解:

Method method = MyClass.class.getMethod("myMethod");
if (method.isAnnotationPresent(MyAnnotation.class)) {
    MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
    System.out.println("方法注解的值: " + myAnnotation.value());
}

示例:基于注解值动态操作

根据注解的信息,你可以进一步决定程序的执行逻辑,例如:

if (myAnnotation != null && "Special Value".equals(myAnnotation.value())) {
    // 执行特定的操作
} else {
    // 执行默认操作
}

注意事项

  • 确保你的注解有运行时保留策略 (@Retention(RetentionPolicy.RUNTIME)),否则它们不会在运行时可见。
  • 当使用反射处理注解时,考虑性能影响,特别是在频繁操作或大型项目中。
  • 利用注解可以极大地增强代码的灵活性和可配置性,但过度使用或设计不当也可能导致代码难以理解和维护。

3. 注解的作用

  • 提供配置信息:注解可以替代XML或其他外部配置文件,直接在代码中提供配置细节。
  • 代码文档化:增强代码的自我解释性,提供方法用途、参数意义等信息。
  • 编译时检查:通过编译时注解处理器进行类型安全检查、格式验证等。
  • 框架集成:许多Java框架(如Spring)使用注解来配置依赖注入、事务管理等。
  • 代码生成:一些工具可以读取注解并据此自动生成代码片段,如序列化/反序列化代码、getter/setter等。
  • 运行时处理:通过反射,应用程序可以在运行时发现和处理注解,实现动态行为。
  • 23
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值