自定义注解的用法,会了的话定义一个@Override同名注解什么的…

1.首先要了解自定义注解的两个元素(元注解)

用来声明注解本身的行为

  • @Target

    • 用来声明注解可以被添加在哪些类型的元素上,如类型、方法和域等。
    传入参数 描述
    TYPE
    METHOD
    CONSTRUCTOR
    FIELD
  • @Retention : 声明注解的保留策略

    关键字 描述
    CLASS 声明注解保存在类文件
    RUNTIME 声明注解保存在JVM运行时
    SOURCE 声明注解保存在源码中
  • @Documented

    • 指明拥有这个注解的元素可以被javadoc此类的工具文档化。这种类型应该用于注解那些影响客户使用带注释的元素声明的类型。如果一种声明使用Documented进行注解,这种类型的注解被作为被标注的程序成员的公共API。
  • @Inherited

    • 指明该注解类型被自动继承。如果用户在当前类中查询这个元注解类型并且当前类的声明中不包含这个元注解类型,那么也将自动查询当前类的父类是否存在Inherited元注解,这个动作将被重复执行知道这个标注类型被找到,或者是查询到顶层的父类。

Java内建注解

Java提供了三种内建注解。

  • @Override

    • 当我们想要复写父类中的方法时,我们需要使用该注解去告知编译器我们想要复写这个方法。这样一来当父类中的方法移除或者发生更改时编译器将提示错误信息。
  • @Deprecated

    • 当我们希望编译器知道某一方法不建议使用时,我们应该使用这个注解。Java在javadoc 中推荐使用该注解,我们应该提供为什么该方法不推荐使用以及替代的方法。
  • @SuppressWarnings

    • 这个仅仅是告诉编译器忽略特定的警告信息,例如在泛型中使用原生数据类型。它的保留策略是SOURCE,并且被编译器丢弃。

      2.开始

a.以此在类中声明一个自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface AnnotationDemo {
    // 声明一个注解
     String name();
    int age() default 0;

}

其中,finished这个注解的默认值是0,也就是可以设置默认值!

b.在某项中注入值
public class AnnotationPriv {


    @AnnotationDemo(name = "Tom",age = 19)
    private String id;
}
c.设置注解的逻辑处理
public class AnnotationUtilDemo {
public static void getFruitInfo(Class<?> clazz){

    String personName ="名称:";
    String personAge = "年龄";

    Field[] fields = clazz.getDeclaredFields();

    for(Field field :fields){
        if(field.isAnnotationPresent(AnnotationDemo.class)){
            AnnotationDemo annotationDemo = (AnnotationDemo) field.getAnnotation(AnnotationDemo.class);
            personName = personName+annotationDemo.name();
            personAge = personAge + annotationDemo.age();
            System.out.println(personName);
            System.out.println(personAge);
            }

        }
    }
}
d.运行
1
2
3
public static void main(String[] args) {
AnnotationUtilDemo.getFruitInfo(AnnotationPriv.class);
}
e.得出结果
名称:Tom   
年龄19

花式注解

现在我有个奇葩需求,两个类同时实现了一个interface,蓝后我要在这两个类上声明一个带值的注解,通过指定值来指定具体的实现类。

谁知道当时我闲的蛋疼的什么奇葩脑洞,可能真实开发中用不到这个玩意,但是开展一下总是好的。

a.声明一个注解

1
2
3
4
5
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ModeCode {
int value() default 1;
}

b.新建一个interface,两个实现类

1
2
3
public interface SayHi{
String SayHi();
}
1
2
3
4
@ModeCode(1)
public class sayHiA implements SayHi{
...
}
1
2
3
4
@ModeCode(2)
public class sayHiB implements SayHi{
...
}

这个时候应该怎么搞啊我需要获取这个interface的全部实现类啊!!

  • google 有一个工具包 auto-service
    这个第三方工具可以找到interface下的所有实现类
1
2
3
4
5
6
ServiceLoader<S> loader = ServiceLoader.load(SayHi.class);
for (S s : loader) {
if (s.getClass().getAnnotation(ModeCode.class).value() == getMode()) {
return (S) ApplicationContextRegister.getBean(s.getClass());
}
}

本文采用CC-BY-SA-3.0协议,转载请注明出处
Author: dadonggua