理解java注解一

     对于java注解,也就是Annotation,大家应该并不陌生。只要你参与了java 的后端开发,那么你一定接触过spring。spring框架中许多功能都是使用注解来实现的。比如:最常见的@Autowired,将spring容器中的对象注入到类中,直接使用,不用再频繁的创建某个类;还有@RequestMapping,通过这个注解,spring中的处理器handler匹配前端传来的请求,然后进入到执行的controller中。对于注解,许多人平时用起来倒是很爽,直接一个@,许多东西都不用自己去配置或者去写了,但是真要去讲下注解,说下实现,就感觉十分迷茫了。

我们先来看下注解的官方解释:

从JDK5开始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特
殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过注解开发人员可以在不改变原有
代码和逻辑的情况下在源代码中嵌入补充信息。

对于这样的解释,一般只有一个字“晕”。而且可能许多人连读的欲望都没有。一般来说,每当我们解释一个抽象名词的时候,会拿一个现实生活中常用的东西来进行类比,以便更好的进行理解,那么问题来了,注解和什么比较类似呢?

对于经常使用注解的我们,都知道添加注解之后,代码就可以进行识别,然后进行相应的校验,对比或者是注入类,就是说注解好像一个标示牌一样,放在那里,一看到就知道了,“哎,那是注解,标示的校验!”

所以大家一般都将注解比较标示牌亦或者一枚标签,醒目而且容易识别,这样理解起来就容易多了。

当然,这样对比的话,注解的一些功能可能没有完全类比出来,所以我又细细想了一下,找打一种东西,和注解很类似——那就是包装盒!

首先包装盒上肯定是有标示的,提示你这是什么东西,有什么作用,这个就类似标签了。其次,现在的包装盒都比较精美,比如月饼盒子,一般同一种盒子只能装一种月饼,装其他种类的话可能或大或小,不太合适,浪费了空间,而且还会让消费者感到不舒服。

让我们来看看注解,首先是标识,讲清楚这个注解的作用,类似于包装盒上的产品介绍之类的。其次是作用,注解一般是进行方法或者属性校验或者说是对比,而包装盒特有的形状就是对外来物的校验,对比,不一致不允许放进来!就好像请求方法或者获取属性值的时候,不符合这个注解根本没有办法进入方法或者获取属性值。

好了,下面我们来说一说常见的java 注解。

首先,我们就从最熟悉的@Autowired这个注解说起。

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER,
 ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
    boolean required() default true;
}

大家可以看到java中的注解使用的是@interface,同时@Autowired这个注解上面还有三个注解,那么这个是什么呢?

说到这个,我们就要先讲一讲元注解了,那么什么是元注解呢?

元注解是可以注解到注解上的注解,或者说元注解是一种基本注解,但是它能够应用到其它的注解上面。或者说是包装盒上面再加了一层包装。

元标签有 @Retention、@Documented、@Target、@Inherited、@Repeatable 5 种。

@Retention

Retention 的英文意为保留期的意思。当 @Retention 应用到一个注解上的时候,它解释说明了这个注解的的存活时间。

它的取值如下:

    RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
    RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
    RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。

@Document

顾名思义,这个元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 Javadoc 中去。

Target 是目标的意思,@Target 指定了注解运用的地方。

你可以这样理解,当一个注解被 @Target 注解时,这个注解就被限定了运用的场景。

类比到包装盒,原本包装盒是你想张贴到哪个地方就到哪个地方,但是因为 @Target 的存在,它用的地方就非常具体了,比如只能去包装方法、类、方法参数等等。@Target 有下面的取值

    ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
    ElementType.CONSTRUCTOR 可以给构造方法进行注解
    ElementType.FIELD 可以给属性进行注解
    ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
    ElementType.METHOD 可以给方法进行注解
    ElementType.PACKAGE 可以给一个包进行注解
    ElementType.PARAMETER 可以给一个方法内的参数进行注解
    ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举

@Inherited

Inherited 是继承的意思,但是它并不是说注解本身可以继承,而是说如果一个超类被 @Inherited 注解过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解

@Repeatable

Repeatable 自然是可重复的意思。@Repeatable 是 Java 1.8 才加进来的,所以算是一个新的特性。

什么样的注解会多次应用呢?通常是注解的值可以同时取多个。

举个例子,一个人他既是程序员又是产品经理,同时他还是个老师。

今天就到这,下次讲注解的简单获取(通过反射)。

猜你喜欢

转载自blog.csdn.net/zsah2011/article/details/90610600
今日推荐