【JDK8新特性】重复注解与类型注解

 
愿你如阳光,明媚不忧伤。

友情链接 【年薪百万之IT界大神成长之路】注解都玩不溜,还怎么称霸IT界(入门篇)!!!

 


1. 重复注解

Repeatable 即一个注解可以在一个类、方法或者字段上同时使用多次。注解并不是什么新鲜东西了,比如 spring 中存在大量注解简化我们的配置。但是在 JDK8 之前,我们是不能使用重复注解的,即某个位置相同注解只能出现一次。

  • Repeatable 源码
    注释类型 java.lang.annotation.Repeatable 用于指示它(元)注释其声明的注释类型是可重复的。 @Repeatable 的值表示可重复注解类型的包含注解类型。
*****************************************************************
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
    /**
     * Indicates the <em>containing annotation type</em> for the
     * repeatable annotation type.
     * @return the containing annotation type
     */
    Class<? extends Annotation> value();
}
*****************************************************************
  • 重复注解示例
    重复注解只是一种简化写法,这种简化写法是一种假象:多个重复注解其实会被作为“容器”注解的value成员 的数组元素处理。
*****************************************************************
public class TestAnnotation {

    public static void main(String[] args) throws NoSuchMethodException {
        Class<TestAnnotation> aClass = TestAnnotation.class;
        Method showPerson1 = aClass.getMethod("showPerson1");
        Person[] persons1 = showPerson1.getAnnotationsByType(Person.class);
        for (Person person : persons1) {
            System.out.println(person.role());
        }
        
        System.out.println("-------------------------------------------");
        
        Method showPerson2 = aClass.getMethod("showPerson2");
        Person[] persons2 = showPerson2.getAnnotationsByType(Person.class);
        for (Person person : persons2) {
            System.out.println(person.role());
        }
    }

    // 使用多重注解(jdk1.8方法)
    @Person(role = "ouseki01")
    @Person(role = "ouseki02")
    @Person(role = "ouseki03")
    public void showPerson1() {
    }

    // 使用包装类当容器来存多个注解(旧版本方法)
    @Persons({@Person(role = "ouseki1"), @Person(role = "ouseki2")})
    public void showPerson2() {
    }

}
................................................................
// 自定义一个包装类 Persons 注解用来放置一组具体的 Person 注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface Persons {
    Person[] value();
}
................................................................
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Persons.class)
@interface Person {
    String role() default "";
}Console-------------------------------------------------------
ouseki01
ouseki02
ouseki03
-------------------------------------------
ouseki1
ouseki2
*****************************************************************

 


2. 类型注解

ElementType java8 以前,注解只能用在各种程序元素(定义类、定义接口、定义方法、定义成员变量…)上。java8 开始新增了两个注解类型,可以用在任何使用到类型的地方。也可以用来支持在 Java 程序中做强类型检查。

  • ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中。
  • ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中(eg:声明语句、泛型和强制转换语句中的类型)。
  • 类型注解示例
    这种无处不在的注解,可以让编译器执行更严格的代码检查,从而提高程序的健壮性。需要指出的是,下面的程序虽然使用了大量 @NotNull 注解,但是这些注解暂时不会起任何作用——因为没有为这些注解提供处理工具,java8 本身并没有提供,要想这些注解发挥作用,需要开发者自己实现,或者使用第三方提供的工具。
*****************************************************************
public class TestAnnotation {

    //在方法形参中使用
    public static void main(@NotNull String[] args) throws NoSuchMethodException {
        Class<TestAnnotation> aClass = TestAnnotation.class;
        Method showPerson1 = aClass.getMethod("showPerson1");
        Person[] persons1 = showPerson1.getAnnotationsByType(Person.class);
        for (Person person : persons1) {
            System.out.println(person.role());
        }
        System.out.println("-------------------------------------------");
        Method showPerson2 = aClass.getMethod("showPerson2");
        Person[] persons2 = showPerson2.getAnnotationsByType(Person.class);
        for (Person person : persons2) {
            System.out.println(person.role());
        }

        Object obj = "ITGodRoad";
        // 使用强制类型转换时使用
        String str = (@NotNull String) obj;
        // 创建对象时使用
        Object win = new @NotNull TestAnnotation();
    }

    // 泛型中使用
    public void foo(List<@NotNull String> info) {
    }

    // 使用多重注解(jdk1.8方法)
    @Person(role = "ouseki01")
    @Person(role = "ouseki02")
    @Person(role = "ouseki03")
    public void showPerson1() {
    }

    // 使用包装类当容器来存多个注解(旧版本方法)
    @Persons({@Person(role = "ouseki1"), @Person(role = "ouseki2")})
    public void showPerson2() {
    }

}
................................................................
// 自定义一个包装类 Persons 注解用来放置一组具体的 Person 注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface Persons {
    Person[] value();
}
................................................................
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Persons.class)
@interface Person {
    String role() default "";
}
................................................................
@Target(ElementType.TYPE_USE)
@interface NotNull {

}Console-------------------------------------------------------
ouseki01
ouseki02
ouseki03
-------------------------------------------
ouseki1
ouseki2
*****************************************************************
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值