Java自定义注解及应用

前言

Java目前只内置了三种标准注解

注解 解释
@Override 表示当前的方法定义将覆盖超类中的方法。如果你不小心拼写错误,或者方法签名对不上被覆盖的方法,编译器就会发出错误提示
@Deprecated 如果程序员使用了注解为它的元素,那么编译器会发出警告信息
@Suppress Warnings 关闭不当的编译器警告信息。在Java SE5之前的版本中,也可以使用该注解,不过会被忽略不起作用

四种元注解,元注解专职负责注解其他的注解

元注解 解释 可选参数
@Target 表示该注解可以用于什么地方。可能的ElementType参数包括 CONSTRUCTOR:构造器的声明
FIELD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类,接口(包括注解类型)或enum声明
@Retention 表示需要在什么级别保存该注解信息。可选的RententionPolicy参数包括 SOURCE:注解将被编译器丢弃器
CLASS:注解在class文件中可用,但会被VM丢弃
@Documented 将此注解包含在javadoc中
@Inherited 允许子类继承父类中的注解

如何在运行时获取注解的值?java在java.lang.reflect包中定义了AnnotatedElement接口,Class,Method,Field等都实现了该接口,通过该接口提供的方法,就可以获得我们需要的信息,并且该接口的方法返回的数组可以由调用方修改,而不影响返回到其他调用方的数组。

AnnotatedElement接口的一部分方法

返回值 方法值 解释
<T extends Annotation>T getAnnotation(Class<T> annotationClass) 该元素如果存在指定类型的注解,则返回这些注解,否则返回 null
Annotation[] getAnnotations() 返回此元素上存在的所有注解,包括从父类继承的
Annotation[] getDeclaredAnnotations() 返回直接存在于此元素上的所有注解,注意,不包括父类的注解,没有则返回长度为0的数组
default boolean isAnnotationPresent(Class<\? extends Annotation> annotationClass) 如果指定类型的注解存在于此元素上,则返回 true,否则返回 false

java.lang.Class中的getDeclared**表示获取自己的东西,而get**方法表示获取自己的和父类的东西,这个接口沿用了这种命名方式

例子

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FruitName {

    // 当不指定默认值时,则必须在写注解的时候写上这个属性的值
    String value() default "";
    String alias() default "";
}
public enum Color {
    BLUE, RED, GREEN
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FruitColor {

    Color fruitColor() default Color.GREEN;
}

测试类

public class Apple {

    // 当只想给value赋值时,可以使用如下快捷方式
    // @FruitName("apple")
    // 当多个属性赋值时,必须采用key=value的形式
    @FruitName(value = "apple", alias = "iphone")
    private String name;

    @FruitColor(fruitColor = Color.RED)
    private String color;

    public static void main(String[] args) {

        Field[] fields = Apple.class.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(FruitName.class)) {
                FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
                // fruitName is apple
                System.out.println("fruitName is " + fruitName.value());
                // alias is iphone
                System.out.println("alias is " + fruitName.alias());
            } else if (field.isAnnotationPresent(FruitColor.class)) {
                FruitColor fruitColor = (FruitColor) field.getAnnotation(FruitColor.class);
                // fruitColor is RED
                System.out.println("fruitColor is " + fruitColor.fruitColor().name());
            }
        }
    }
}

应用

参考我另一篇博文:https://blog.csdn.net/zzti_erlie/article/details/80881461

参考博客

好文
[1]https://blog.csdn.net/javazejian/article/details/71860633
[2]https://www.cnblogs.com/ITtangtang/p/3974531.html
[3]https://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
一个系列
[1]http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
[2]http://www.cnblogs.com/peida/archive/2013/04/26/3038503.html
@Inherited注解的运用
[1]http://xiangdefei.iteye.com/blog/1044199
[2]http://blog.sina.com.cn/s/blog_605f5b4f0100i77k.html

欢迎关注

喜欢本文的朋友们,欢迎关注公众号Kruskal,收看更多精彩内容
avatar

猜你喜欢

转载自blog.csdn.net/zzti_erlie/article/details/80829569