Java注解浅析

在开发过程中,我们经常使用各种各样的注解,诸如@Controller、@Service、@Mapper等,是不是有好多码农像我一样机械的复制或者敲几个注解,知道加几个注解有什么样的效果却没有具体的去了解注解?就像我们每天跟隔壁邻居打招呼却不知道他们怎么称呼,是做什么工作的。
一、认识注解
关于注解,我个人理解注解就相当于一个标签,贴在商品上顾客就知道这个商品卖多少钱,打不打折。我们把一个注解放在一个方法上,我们就可以看出这个方法是不是重写、覆盖的接口的方法,这个方法是不是废弃、过时的方法。

/*@Override注解表示该方法是实现的接口的方法*/
@Override
public Motto getMottoById(Integer id) {
    return this.mottoMapper.getMottoById(id);
}

二、自定义注解
我们通过自定义一个注解来了解下注解的工作原理,在开始编码之前,我们先介绍两个java自带的元注解(在自定义注解时使用到的注解称为元注解)。
@Retention
@Retention定义了该注解被保留的时间长短:某些注解仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的注解可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。我们看@Retention的源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

只有一个枚举类型的value属性,我们看RetentionPolicy的源码:

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

RetentionPolicy可取三个值:RESOURCE、CLASS、RUNTIME,分别表示该自定义注解是存活到源码阶段还是存活到编译成的class文件中,还是存活到运行阶段。
@Target
@Target说明了注解所修饰的对象范围,:注解可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在注解类型的声明中使用了target可更加明晰其修饰的目标。
@Target的源码和@Retention的类似,我就偷下懒不复制出来了,也是一个value属性表示注解所修饰的对象的范围。
总之@Retention从时间上定义了该注解能活多久,@Target从空间上定义了该注解能在那些地方活动。
好了,下面我们来演示一个自定义注解
首先,我们新建一个注解类MyAnnotation

package com.example.demo.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by yuxl on 2019/1/16.
 * @Retention(RetentionPolicy.RUNTIME)表示该注解可以活到运行期
 * @Target({ElementType.TYPE,ElementType.METHOD})表示该注解可以放在类上、方法上
 * 我们给该自定义注解定义了两个string类型的属性value和color
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyAnnotation {
    String value();
    String color();
}

我们建个测试类来测试一下

package com.example.demo;

import com.example.demo.annotation.MyAnnotation;

/**
 * Created by yuxl on 2019/1/16.
 * 将我们自定义的注解贴在测试类上,给注解类的两个属性赋值
 * 通过测试类得到该类上使用的注解的实例,打印出注解的属性值
 */
@MyAnnotation(value="car",color = "green")
public class TestAnnotation {
    public static void main(String[] args){
        //检测TestAnnotation类是否有注解
        if(TestAnnotation.class.isAnnotationPresent(MyAnnotation.class)){
            //获取注解实例
            MyAnnotation myAnnotation = TestAnnotation.class.getAnnotation(MyAnnotation.class);
            //打印出注解属性
            System.out.println("The color is "+ myAnnotation.color()+"! The " + myAnnotation.value()+" can go!");
        }
    }
}

执行代码,输出打印结果:
在这里插入图片描述

更多详细的介绍可以参阅https://www.cnblogs.com/xdp-gacl/p/3622275.html

感谢大家百忙之中抽出宝贵的时间阅读本文,欢迎大家批评指正。微信扫下面二维码添加公众号议码评川,可获取java web、大数据、人工智能等相关学习资料。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值