java元注解作用及使用详解

对于元注解你了解吗?下面的文章内容要给大家介绍的就是java元注解作用及使用方面的内容,一起来了解一下吧。

元注解:

是负责对其它注解进行说明的注解,自定义注解的时候,可以使用元注解。Java 5定义了@Documented、@Target、@Retention和@Inherited这4个注解,Java 8又增加了@Repeatable和@Native这两个注解,这些注解都可以在java.lang.annotation包中找到。

下面的话,要给大家介绍一下,每个元注解的作用和使用。

1、@Documented

@Documented是一个标记注解,没有成员变量,用@Documented注解修饰的注解类会被JavaDoc工具提取成文档,在默认的情况下,JavaDoc是不包括注解的,可是,假如声明注解时指定了@Documented,就会被JavaDoc之类的工具处理,所以注解类型信息就会被包括在生成的帮助文档中。

下面的话,就通过示例来了解一下它的用法吧!

代码:

示例1:

@Documented
@Target(
{
    ElementType.TYPE
    , ElementType.METHOD
})
public @interface MyDocumented
{
    public String value() default "这是@Documented注解";
}

测试类:

@MyDocumented
public class DocumentedTest
{
    /**
     * 测试document
     */
    @MyDocumented
    public String Test()
    {
        return "C语言中文网Java教程";
    }
}

打开Java文件所在的目录,分别输入下面的两条命令行:

javac MyDocumented.java DocumentedTest.java
javadoc -d doc MyDocumented.java DocumentedTest.java

在运行成功之后,打开生成的帮助文档,能够看到在类和方法上都保留了MyDocument的注解信息,如下所示:

MyDocument注解信息

2、@Target

@Target注解用来指定一个注解的使用范围,也就是被@Target修饰的注解可以用在什么地方,@Target注解有一个成员变量(value)用来设置适用目标,value是java.lang.annotation.ElementType枚举类型的数组,下面是ElementType常用的枚举常量。

ElementType常用的枚举常量

示例2:

自定义一个MyTarget注解,使用范围为方法,代码:

@Target(
{
    ElementType.METHOD
})
public @interface MyTarget
{}
class Test
{
    @MyTarget
    String name;
}

在上述代码当中,第6行会编译错误,错误信息为:

The annotation @MyTarget is disallowed for this location

3、@Retention

@Retention用来描述注解的生命周期,也就是这个注解被保留的时间长短。@Retention注解中的成员变量(value)用来设置保留策略,value是java.lang.annotation.RetentionPolicy 枚举类型,RetentionPolicy有3个枚举常量。

如下:

RetentionPolicy3个枚举常量

生命周期大小排序为SOURCE < CLASS < RUNTIME,前者能使用的地方后者一定也能使用,假如,需要在运行时去动态获取注解信息,那只能用RUNTIME注解;假如,要在编译时进行一些预处理操作,例如,生成一些辅助代码(如 ButterKnife),就用CLASS注解;假如,只是做一些检查性的操作,例如,@Override和@SuppressWarnings,那么,可选用SOURCE注解。

4、@Inherited

@Inherited是一个标记注解,用来指定该注解可以被继承,使用@Inherited注解的Class类,表示这个注解可以被用于该Class类的子类,就是说如果某个类使用了被@Inherited修饰的注解,则其子类将自动具有该注解。

示例3:

创建一个自定义注解,代码如下:

@Target(
{
    ElementType.TYPE
})
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyInherited
{}

测试类代码:

@MyInherited
public class TestA
{
    public static void main(String[] args)
    {
        System.out.println(TestA.class.getAnnotation(MyInherited.class));
        System.out.println(TestB.class.getAnnotation(MyInherited.class));
        System.out.println(TestC.class.getAnnotation(MyInherited.class));
    }
}
class TestB extends TestA
{}
class TestC extends TestB
{}

运行结果:

@MyInherited()
@MyInherited()
@MyInherited()

5、@Repeatable

@Repeatable注解是Java 8新增加的,它允许在相同的程序元素中重复注解,在需要对同一种注解多次使用时,往往需要借助@Repeatable注解。Java 8版本以前,同一个程序元素前最多只能有一个相同类型的注解,假如,需要在同一个元素前使用多个相同类型的注解,那么必须使用注解“容器”。

示例4:

Java 8之前的做法:

public @interface Roles
{
    Role[] roles();
}
public @interface Roles
{
    Role[] value();
}
public class RoleTest
{
    @Roles(roles = {
        @Role(roleName = "role1")
        , @Role(roleName = "role2")
    })
    public String doString()
    {
        return "这是C语言中国网Java教程";
    }
}

Java 8之后增加了重复注解,使用方式:

public @interface Roles
{
    Role[] value();
}
@Repeatable(Roles.class)
public @interface Role
{
    String roleName();
}
public class RoleTest
{
    @Role(roleName = "role1")
    @Role(roleName = "role2")
    public String doString()
    {
        return "这是C语言中文网Java教程";
    }
}

区别在于,创建重复注解Role时加上了@Repeatable注解,指向存储注解Roles,这样在使用时就可以直接重复使用Role注解。从上面例子看出,使用@Repeatable注解更符合常规思维,可读性强一点。

两种方法获得的效果相同,重复注解只是一种简化写法,这种简化写法是一种假象,多个重复注解其实会被作为“容器”注解的value成员的数组元素处理。

6、@Native

使用@Native注解修饰成员变量,那么,表示这个变量可以被本地代码引用,常常被代码生成工具使用。

以上的内容你都清楚了吗?更多java入门内容,可以继续通过本站来进行了解哦。

推荐阅读:

java @FunctionalInterface注解详解

java @SafeVarargs注解详解

java注解(Annotation)概念和作用介绍