说说 Java 注解

Java 注解可以看做是 Javadoc 和 Xdoclet 标签的延伸和发展,我们可以自定义注解标签,并通过 Java 语言的反射机制来获取类中标注的注解,完成特定的功能 。

注解是代码的附属信息,无论增加还是删除注解,都不会影响程序代码的运行。因为 Java 语言解释器会忽略这些注解,而让第三方工具负责对注解进行处理 。 第三方工具可以利用代码中的注解间接控制程序代码的运行,它们通过 Java 反射机制读取注解的信息,并根据这些信息更改逻辑 。

1 定义

我们使用 @interface 来定义注解类。

示例:

@Retention(RetentionPolicy.RUNTIME)//保留期限
@Target(ElementType.METHOD)//目标类型
public @interface Log {
    boolean value() default true;//声明成员变量
}

示例中的 @Retention@Target 被称为元注解(Meta-annotation)。

1.1 成员变量

可以在注解类中定义多个成员变量,成员变量的定义语法有以下这些要求:

  • 不能定义入参。
  • 不能抛出异常。
  • 可以通过 default 定义一个默认值。
  • 合法的成员类型有这些 - 原始类型及其封装类、Class、enums、注解类型和包含上述类型的数组类型。
  • 如果注解类只有一个成员变量,那么必须名为 value()。在使用时可以忽略成员名称和赋值符号(=),比如可以这样使用示例中的注解 @Log(true)
  • 如果注解类拥有多个成员变量,如果仅对 value 进行赋值,则也可以忽略成员名称和赋值符号(=)。
  • 如果注解类拥有多个成员变量,又需要同时对多个成员变量进行赋值,那么就必须使用成员名称加赋值号表示,比如事务注解:@Transactional(propagation= Propagation.MANDATORY,isolation= Isolation.DEFAULT)
  • 注解类可以没有成员变量,这样注解类被称为标注注解,由调用程序负责判断处理。
  • 注解类不能继承其它类,也不能实现其它接口。

1.2 保留期限 @Retention

@Retention 表示保留期限,它被定义在 java.lang.annotation.RetentionPolicy 中:

保留期限类型 说明
SOURCE 注解信息仅保留在源代码文件中。
CLASS 注解信息保留在源代码文件与字节码文件中。
RUNTIME 注解信息不仅保留在源代码文件与字节码文件中,而且会被加载到 JVM 中,在运行期可以通过反射读取这些注解信息。

1.3 目标类型 @Target

@Target 表示注解的应用目标类型。它被定义在 java.lang.annotation.ElementType 中。

目标类型 说明
TYPE 类、接口、注解类型、Enum 处声明。
FIELD 成员变量、Enum 常量处声明。
METHOD 方法处声明。
PARAMETER 参数处声明。
CONSTRUCTOR 构造函数处声明。
LOCAL_VARIABLE 局部变量处声明。
ANNOTATION_TYPE 注解类处声明。
PACKAGE 包处声明。
TYPE_PARAMETER 类型参数处声明。(1.8 新增)
TYPE_USE 使用类型处声明。(1.8 新增)

2 配置注解

public class User {

    @Log()
    public void rent(String userId) {
        System.out.println("User:租赁【充电宝】");
    }

    @Log(false)
    public void back(String userId){
        System.out.println("User:归还【充电宝】");
    }
}

这里直接在需要的方法上,加入注解类。

标注注解的格式为:

@<注解名>(<成员名1>=<成员值1>,<成员名2>=<成员值2>,...)

如果成员变量是数组类型,就可以通过{} 进行赋值。

说明 示例
单成员注解 @Service("userService")
多成员注解 @Transactional(propagation= Propagation.MANDATORY,isolation= Isolation.DEFAULT)
无成员注解 @Override
成员类型为普通数组 @SuppressWarnings(value={"unchecked", "rawtypes"})
成员类型为注解数组 @ComponentScans({@ComponentScan("1.xml"),@ComponentScan("2.xml")})

3 获取注解

对于保留期限为 RetentionPolicy.RUNTIME 的注解,可以通过反射来获取注解信息 。

在 Java5.0 中, Package、Class、Constructor、Method 以及 Field 等反射对象都新增了访问注解的多种方法,它们都支持泛型。

Class clazz = User.class;
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
    //获取注解
    Log log = method.getAnnotation(Log.class);
    if (log != null) {
        if (log.value()) {
            System.out.println(method.getName() + "() 方法需要记录日志");
        } else {
            System.out.println(method.getName() + "() 方法不需要记录日志");
        }
    }
}

输出结果:

back() 方法不需要记录日志
rent() 方法需要记录日志

是不是很简单呀 O(∩_∩)O哈哈~

猜你喜欢

转载自blog.csdn.net/deniro_li/article/details/80761881
今日推荐