Java 注解Annotation运用2

200 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情

定义Annotation

我们使用@interface来定义一个注解

image.png

常见标准的Annotation

从java5版本开始,自带了三种标准annontation类型,

1、Override

java.lang.Override 是一个marker annotation类型,它被用作标注方法。它说明了被标注的方法重载了父类的方法,起到了断言的作用。如果我们使用了这种annotation在一个没有覆盖父类方法的方法时,java编译器将以一个编译错误来警示。

这个annotaton常常在我们试图覆盖父类方法而确又写错了方法名时加一个保障性的校验过程。

2、Deprecated

Deprecated也是一种marker annotation。当一个类型或者类型成员使用@Deprecated修饰的话,编译器将不鼓励使用这个被标注的程序元素。所以使用这种修饰具有一定的 “延续性”:如果我们在代码中通过继承或者覆盖的方式使用了这个过时的类型或者成员,虽然继承或者覆盖后的类型或者成员并不是被声明为 @Deprecated,但编译器仍然要报警。

注意:@Deprecated这个annotation类型和javadoc中的 @deprecated这个tag是有区别的:前者是java编译器识别的,而后者是被javadoc工具所识别用来生成文档(包含程序成员为什么已经过时、它应当如何被禁止或者替代的描述)。

3、SuppressWarnings

此注解能告诉Java编译器关闭对类、方法及成员变量的警告。

有时编译时会提出一些警告,对于这些警告有的隐藏着Bug,有的是无法避免的,对于某些不想看到的警告信息,可以通过这个注解来屏蔽。

SuppressWarning不是一个marker annotation。它有一个类型为String[]的成员,这个成员的值为被禁止的警告名。对于javac编译器来讲,被-Xlint选项有效的警告名也同样对@SuppressWarings有效,同时编译器忽略掉无法识别的警告名。

annotation语法允许在annotation名后跟括号,括号中是使用逗号分割的name=value对用于为annotation的成员赋值:

@SuppressWarnings(value={"unchecked","fallthrough"})

public void lintTrap() { /* sloppy method body omitted */ }

在这个例子中SuppressWarnings annotation类型只定义了一个单一的成员,所以只有一个简单的value={...}作为name=value对。又由于成员值是一个数组,故使用大括号来声明数组值。

注意:我们可以在下面的情况中缩写annotation:当annotation只有单一成员,并成员命名为"value="。这时可以省去"value="。比如将上面的SuppressWarnings annotation进行缩写:

@SuppressWarnings({"unchecked","fallthrough"})

如果SuppressWarnings所声明的被禁止警告个数为一个时,可以省去大括号:

@SuppressWarnings("unchecked")

自定义annontation示例

示例共涉及四个类:

清单1:Author.java

package com.magc.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @Documented
public @interface Author {

        String name();
        String group();
}

清单2:Description.java


import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    
public @interface Description {
        String value();
}

清单3:Utility.java

    @Description(value = "这是一个有用的工具类")
public class Utility {

        @Author(name = "xxx",group="hhh")
        public String work()
        {
            return "work over!";
        }
        
        
    
}

注:这是个普通的Java类,运行了@Description和@Author注解。

清单3:AnalysisAnnotation.java

import java.lang.reflect.Method;

public class AnalysisAnnotation {
    /**
     * 在运行时分析处理annotation类型的信息
     * 
     * 
     */
    public static void main(String[] args) {
        try {
                //通过运行时反射API获得annotation信息
                Class rt_class = Class.forName("com.magc.annotation.Utility");
                Method[] methods = rt_class.getMethods();
                
                boolean flag = rt_class.isAnnotationPresent(Description.class);
                
                if(flag)
                {
                    Description description = (Description)rt_class.getAnnotation(Description.class);
                    System.out.println("Utility's Description--->"+description.value());
                    for (Method method : methods) {
                        if(method.isAnnotationPresent(Author.class))
                        {
                            Author author = (Author)method.getAnnotation(Author.class);
                            System.out.println("Utility's Author--->"+author.name()+" from "+author.group());
                            
                        }
                    }
                }
            
            
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    }

}

注:这是个与自定义@Description和@Author配套的基础框架或工具类,通过此类来获得与普通Java类Utility.java关联的信息,即描述和作者。

运行AnalysisAnnotation,输出结果为:

  • Utility's Description--->这是一个有用的工具类
  • Utility's Author--->xxx from hhh

总结

本文只是抛砖引玉地讲解了Annotation的基本理解,Annotation的作用,Annotation的功用以及使用方法,并通过一个简单的例子讲解了一下Annotation的处理。