美文网首页程序员
Java的Annotation

Java的Annotation

作者: brackenbo | 来源:发表于2019-01-15 22:02 被阅读0次

    提到annotation想必大家都不会陌生,因为基本上JAVA的工程中随处可见annotation的身影。

    • Override: 这个annotation表明此方法是在接口中声明过或者抽象类中需要被实现的
    • Autowired: spring框架中,声明某个方法或者属性是作为bean存在的
    • Data/getter: lomok包里面的,省去书写getter和setter等的annotation

    annotation实际上是利用了Java的反射原理,来对类的属性等遍历进行处理。

    Annotation 含义

    An annotation is a marker which associates information with a program construct, but has no effect at run time.

    annotation是用来标记程序代码的相关信息的标识符。annotation不会对程序的运行时产生影响。但是它会给运行时代码提供信息。

    构造一个Annotation

    我们来了解一下如何构造一个新的Annotation,这样就可以对经常使用的@Autowired @Data等原理有一个了解。

    示例如下:

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface Rename {
        public String value() default "";
    }
    
    • @interface:表明这是一个annotation的声明
    • @Retention:表明这个annotation的生命周期,RUNTIME是指在整个运行时,后续会看到Retention会有其他的几个类型
    • Target: 表明这个annotation会在哪些范围起作用,FIELD指的是属性上起作用
    • value: 表明了属性有一个对应的String类型的值,默认为空字符串

    有了这个定义,我们可以在属性上来使用:

    public class Building {
    
        @Rename("bName")
        private String name;
    
        @Rename("bCity")
        private String city;
    
    
    private Integer height;
    }
    

    Annotation的处理

    上面我们只看到,定义了一个annotation,那么对于像Autowired这种,是在什么地方去处理的呢,下面我们就来展示一下,通过Rename这个annotation来打印所有的属性的别名。

    • 拿到Building对象对应的类

    • 获取所有的属性

    • 设置属性为可读

    • 获取annotation对应的值

    • 输出结果

      public String process(Object object) {
      
        Class<?> aClass = requireNonNull(object).getClass();
      
      
        List<String> properties = Arrays.asList(aClass.getDeclaredFields())
                .stream()
                .filter(field -> field.isAnnotationPresent(Rename.class))
                .map(field -> {
                    field.setAccessible(true);
                    try {
                        return field.getAnnotation(Rename.class).value() + ": " + field.get(object);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                        return "";
                    }
                })
                .collect(Collectors.toList());
      
        return String.join("\r\n", properties);
      }
      

    可以查看一下结果:

    @Test
    public void shouldRenameBuilding() {
    ProcessRename processRename = new ProcessRename();

        Building building = new Building();
        building.setCity("sydney");
        building.setName("kongn");
    
        String process = processRename.process(building);
        System.out.println(process);
    }
    

    输出结果:

    bName: kongn
    bCity: sydney
    

    Retention和Target

    • Rentention的类型有如下三种:
    Policy Description
    Source Annotations 会被编译器丢弃掉,例如@override
    Class Annotations只在编译期起作用
    Runtime Annotations被编译器标记为在运行时起作用
    • Target的类型:
    Target Description
    Annotation Type Annotates another annotation
    Constructor Annotates a constructor
    Field Annotates a field, such as an instance variable of a class or an enum constant
    Local variable Annotates a local variable
    Method Annotates a method of a class
    Module Annotates a module (new in Java 9)
    Package Annotates a package
    Parameter Annotates a parameter to a method or constructor
    Type Annotates a type, such as a class, interfaces, annotation types, or enum declarations
    Type Parameter Annotates a type parameter, such as those used as formal generic parameters
    Type Use Annotates the use of a type, such as when an object of a type is created using the newkeyword, when an object is cast to a specified type, when a class implements an interface, or when the type of a throwable object is declared using the throws keyword (for more information, see the Type Annotations and Pluggable Type Systems Oracle tutorial)

    相关文章

      网友评论

        本文标题:Java的Annotation

        本文链接:https://www.haomeiwen.com/subject/xiuydqtx.html