女朋友说想要自己的注解,我又活下来了!!!

开发 前端
你spring学的不错,那我先带你参观下Autowired吧~看到 「Autowired」 发现,这个类的「类名就叫 Autowired」,所以你知道为什么贴的是 @Autowired 了吗?

[[416903]]

女朋友:我想要我自己的注解,你教我!

moon:诶?你怎么突然想要自己的注解了?

女朋友:关你什么事!「分手」!

moon:别别别别别!我教!

moon:看好了,我的宝~,你spring学的不错,那我先带你参观下Autowired吧~

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented 
public @interface Autowired { 
 /** 
  * Declares whether the annotated dependency is required. 
  * <p>Defaults to {@code true}. 
  */ 
 boolean required() default true

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

moon:看到 「Autowired」 发现,这个类的「类名就叫 Autowired」,所以你知道为什么贴的是 @Autowired 了吗?

女朋友:哦哦哦哦哦哦!我懂了!原来「类名就是注解名」!

moon:我女朋友就是聪明!我们再来看看,它还有一点比较特殊的地方,类的标志是 class,而「注解的标志是 @interface」。

女朋友:嗯.....不错不错,你继续

moon:我们再来看下 @Autowired 上面还有三个注解,分别是什么作用,先来看第一个 「@Documented」

/** 
 * Indicates that annotations with a type are to be documented by javadoc 
 * and similar tools by default.  This type should be used to annotate the 
 * declarations of types whose annotations affect the use of annotated 
 * elements by their clients.  If a type declaration is annotated with 
 * Documented, its annotations become part of the public API 
 * of the annotated elements. 
 * 
 * @author  Joshua Bloch 
 * @since 1.5 
 */ 
@Documented 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.ANNOTATION_TYPE) 
public @interface Documented { 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

moon:看,我们发现了,第一个是 @Documented,我们来看看它的注释是什么?

图片

moon:通过我强大的英文阅读能力,发现 「@Documented 注解其实只是用来生成文档的」,使用 javadoc 就可以生成 api 文档了,所以这个注解,肯定「不重要」

女朋友:呸!你明明是靠翻译的!学渣!

moon:嘿嘿,我们再来看下一个!「@Retention」!这个可有的说头了。

/** 
 * Indicates how long annotations with the annotated type are to 
 * be retained.  If no Retention annotation is present on 
 * an annotation type declaration, the retention policy defaults to 
 * {@code RetentionPolicy.CLASS}. 
 * 
 * <p>A Retention meta-annotation has effect only if the 
 * meta-annotated type is used directly for annotation.  It has no 
 * effect if the meta-annotated type is used as a member type in 
 * another annotation type. 
 * 
 * @author  Joshua Bloch 
 * @since 1.5 
 * @jls 9.6.3.2 @Retention 
 */ 
@Documented 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.ANNOTATION_TYPE) 
public @interface Retention { 
    /** 
     * Returns the retention policy. 
     * @return the retention policy 
     */ 
    RetentionPolicy value(); 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.

moon:再次通过我强大的英文阅读能力看下,这个注释到底是什么意思?

图片

moon:其实它就是告诉你,该注解的「生命周期」有多久,而这个生命周期的定义,「就在 RetentionPolicy 里面」,我们再来看看这个 RetentionPolicy 到底是什么?

public enum RetentionPolicy { 
    /** 
     * Annotations are to be discarded by the compiler.关注公众号:moon聊技术,获取更多有趣文章 
     */ 
    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 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

女朋友:这个我熟!「SOURCE 的意思就是说被作用在源代码上,CLASS 就是被作用在编译出来的源码上,RUNTIME 就是只作用在运行时」!这不就是 Java 的三种状态嘛!

moon:你都学会抢答了我的宝!!!!

女朋友:哼!快继续!!

moon:哈哈哈,好的,那我们就来说说最后一个注解 「@Target」

@Documented 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.ANNOTATION_TYPE) 
public @interface Target { 
    /** 
     * Returns an array of the kinds of elements an annotation type 
     * can be applied to
     * @return an array of the kinds of elements an annotation type 
     * can be applied to 
     */ 
    ElementType[] value(); 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

moon:这个注解的作用其实很简单,「就是告诉你该注解可以被贴在哪些作用域中」,而作用域有哪些你知道吗?

女朋友:嗯...有类、方法、成员变量.....

moon:哈哈哈哈哈,不知道了吧!!

女朋友:哼!!「分手」!!!!

moon:别别别别别别,听我给你娓娓道来!这个作用域其实就藏在 「ElementType[]」 这个数组当中,我们进去看下!

public enum ElementType { 
    /** Class, interface (including annotation type), or enum declaration 关注公众号:moon聊技术,获取更多有趣文章*/ 
    TYPE, 
 
    /** Field declaration (includes enum constants) */ 
    FIELD, 
 
    /** Method declaration */ 
    METHOD, 
 
    /** Formal parameter declaration */ 
    PARAMETER, 
 
    /** Constructor declaration */ 
    CONSTRUCTOR, 
 
    /** Local variable declaration */ 
    LOCAL_VARIABLE, 
 
    /** Annotation type declaration */ 
    ANNOTATION_TYPE, 
 
    /** Package declaration */ 
    PACKAGE, 
 
    /** 
     * Type parameter declaration 
     * 
     * @since 1.8 
     */ 
    TYPE_PARAMETER, 
 
    /** 
     * Use of a type 
     * 
     * @since 1.8 
     */ 
    TYPE_USE 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.

moon:总共有「10种作用域」

所以当你确定你注解的作用域之后,你贴上 @Target(作用域),就可以了!

女朋友:噢噢噢噢,我懂了,那我有个问题,「如果我想让我的子类也继承这个注解该怎么做呢」?

moon:!!!!!!!这就是我接下来要讲的!!「@Inherited」 !!也是 java 四大元注解之一(还有三个就是刚刚提到的@Target,@Retention,@Documented)!它的作用就是「让子类也能继承该父类的该注解」,那你知道该怎么用嘛?

女朋友:分....

moon:我来给你举个例子!正好练习一下!

女朋友:哼!

moon:我们先写个注解类

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface MyAnnotation { 
    /** 
     * 说我爱你(默认true
     */ 
    boolean sayILoveYou() default true

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

moon:这个注解很简单,「只能作用在方法上,在运行时实现,有个 syaILoveYou 的方法,默认是true!」

女朋友:yue~快说

moon:哈哈,再定义一个我,有个 sayLoveYou()方法,贴上了我们的 @MyAnnotation 注解,表达一下我的真心

public class Me { 
    @MyAnnotation 
    public void sayLoveYou(){ 
        System.out.println("表达一下我的真心"); 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

女朋友:yue~

moon:好了,现在我们开始测试了!

public class Main { 
    public static void main(String[] args) { 
        try { 
            //获取Me的Class对象 
            Me me = new Me(); 
            Class clazz = me.getClass(); 
            //获取该对象sayLoveYou方法上Info类型的注解 
            MyAnnotation myAnnotation = clazz.getMethod("sayLoveYou"null).getDeclaredAnnotation(MyAnnotation.class); 
            if (myAnnotation.sayILoveYou()) { 
                System.out.println("我爱你"); 
            } else { 
                System.out.println("我不爱你"); 
            } 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

moon:我们先获取到了 Me 的对象,然后获取到了 MyAnnotation 这个注解,如果 myAnnotation.sayILoveYou() 为true,就会输出"我爱你"!如果为false,就会输出"我不爱你"!

女朋友:你不爱我,「我们分手」

moon:咳咳,测试测试~我们运行看下,结果一定是我爱你!因为我们默认为true

图片

moon:我们修改下注解的默认值,结果就为我EN爱你了(满满的求生欲)

public class Me { 
    @MyAnnotation(sayILoveYou=false
    public void sayLoveYou(){ 
        System.out.println("表达一下我的真心"); 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
图片

女朋友:哼~

moon:我们再试验下 @Inherited 这个注解,修改下 MyAnnotation,「添加 @Inherited」,添「加 ElementType.TYPE 并且使其可以作用在类上」

@Retention(RetentionPolicy.RUNTIME) 
@Target({Ele,mentType.METHOD,ElementType.TYPE}) 
@Inherited 
public @interface MyAnnotation { 
    /** 
     * 说我爱你(默认true
     */ 
    boolean sayILoveYou() default true

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

moon:Me 这个类在类上贴 @MyAnnotation 注解

@MyAnnotation 
public class Me { 
    public void sayLoveYou(){ 
        System.out.println("表达一下我的真心"); 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

moon:然后我们假如有孩子了

public class Child extends Me{ 

  • 1.
  • 2.

女朋友:我不会和你结婚的!

moon:哈哈哈,假设假设,我们再来重写 Main 方法

public static void main(String[] args) { 
   try { 
       //获取child的Class对象 
       Child child = new Child(); 
       Class clazz = child.getClass(); 
       //获取该对象sayLoveYou方法上Info类型的注解 
       MyAnnotation myAnnotation = (MyAnnotation) clazz.getAnnotation(MyAnnotation.class); 
       if (myAnnotation.sayILoveYou()) { 
           System.out.println("我爱你"); 
       } else { 
           System.out.println("我不爱你"); 
       } 
   } catch (Exception e) { 
       e.printStackTrace(); 
   } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

moon:「我们此时 child 对象是没有 @MyAnnotation 注解的,只是继承了我,但是由于我们再 Me 类贴了 @MyAnnotation 注解,并且有 @Inherited 注解,所以 child 也有该注解的功能,所以运行结果一定是我爱你!」

图片

moon:这下你会了吧!注解就是这么简单!

女朋友:哼,你还是有点用的,我不需要你了,你走吧

moon:好的老板!(终于教会了,我又活下来了)

一共分了多少次手,你们数清楚了吗?

 

责任编辑:姜华 来源: moon聊技术
相关推荐

2019-04-16 14:31:21

华为离职移动

2021-03-03 09:16:51

容器技术容器云计算

2018-04-24 18:23:02

数据库误删

2020-11-08 14:34:31

小视频浏览器

2024-03-28 09:24:31

AI语言模型技术

2019-07-22 09:55:43

误删数据库用户库

2020-01-02 09:14:23

Kubernetes内部容器

2019-10-24 09:29:04

程序员程序员节女朋友

2019-11-19 11:29:50

Python数据标系

2019-08-28 16:22:30

Python数据微信

2023-04-12 08:45:21

ChatGPTPrompt技巧

2015-08-26 10:17:29

程序员女朋友

2021-02-20 07:52:35

防猝死插件 IDEA

2021-02-02 11:59:15

插件开发工具

2022-09-17 08:10:20

HSV饱和度图像

2020-04-21 11:45:04

技巧单一责任链开闭原则

2013-01-04 10:20:27

互联网产品

2020-09-02 08:52:16

地图Echarts可视化

2019-07-01 09:31:04

拉黑复活检测器

2019-07-09 09:19:51

分布式事务App
点赞
收藏

51CTO技术栈公众号