专栏首页moon聊技术女朋友说想要自己的注解,我又活下来了!!!

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

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

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;
}

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 {
}

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();
}

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
}

女朋友:这个我熟!「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();
}

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
}

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

作用域

含义

TYPE

用于描述类、接口(包括注解类型) 或enum声明

FIELD

用于描述域

METHOD

用于方法

PARAMETER

用于描述参数

CONSTRUCTOR

用于描述构造器

LOCAL_VARIABLE

用于描述局部变量

ANNOTATION_TYPE

用于描述注解

PACKAGE

用于描述包

TYPE_PARAMETER

表示该注解能使用在自定义类型参数

TYPE_USE

是对类型的注解

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

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

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

女朋友:分....

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

女朋友:哼!


moon:我们先写个注解类

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

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

女朋友:yue~快说

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

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

女朋友: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();
        }
    }
}

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

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

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

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

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

女朋友:哼~

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

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

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

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

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

public class Child extends Me{
}

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

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();
   }
}

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

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

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

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

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

本文分享自微信公众号 - moon聊技术(onetraveller_llxz),作者:moon聊技术

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-08-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 程序员开发了一款软件,完成了舔狗的绝地反杀(代码开源)!

    https://github.com/tangzixiang0304/Shielded_detector/raw/master/dist/detector.ex...

    良月柒
  • 他被女朋友拉黑后,写了个“舔狗”必备神器

    在一个阳光明媚的清晨,我打开窗户呼吸了一口新鲜空气。阳光灿烂,岁月静好,又是一个约女朋友出去爬山吃饭看电影的好日子。

    小小詹同学
  • 我开发了一款软件,完成了舔狗的绝地反杀(代码开源)!

    https://github.com/tangzixiang0304/Shielded_detector/raw/master/dist/detector.ex...

    Python进击者
  • 我开发了一款软件,完成了舔狗的绝地反杀(代码开源)!

    https://github.com/tangzixiang0304/Shielded_detector/raw/master/dist/detector.ex...

    小小詹同学
  • 怎么用机器学习技术找到女票?

    机器学习在我们生活中的用处有多大,就不用我们多说了,大到医疗诊断,小到手机应用,机器学习都应用的风风火火。但是用机器学习帮自己在学校找对象,你听说过...

    加米谷大数据
  • 给女朋友讲解什么是Git

    https://www.bilibili.com/video/BV1xb411A7ac?from=search&seid=4239535088233137638

    Java3y
  • 程序猿真的觉得写代码比女朋友重要吗?

    IT架构圈
  • 【玩转腾讯云】教你如何用音视频工具FFmpeg充实自己的生活

    经常听到女同学和女同事抱怨,说程序猿不懂得浪漫,时间久了,仿佛我们程序猿也慢慢接受了这样的标签。其实,只要我们有一个有想法的心,就能创造出属于我们程序猿的浪漫。...

    liuzhen007
  • 史上最污技术解读,我竟然秒懂了!

    很多同学对热备,冷备,云备了解不深,我科普一下 IT 行业各种备份术语。以后别闹笑话了。

    用户1516716
  • 教女朋友读懂数据中台

    与女朋友有了共同话题,感情是一日千里,但压力也与日俱增。毕竟我对技术的理解也只是能在女朋友面前显摆显摆的水平。

    了不起的云计算
  • 陌生美女加你微信好友后的N个体验

    身为举报小助手,每天耳闻目览诸多用户举报的案例,层出不穷的网络违法行为让小助手感到深恶痛绝。因此,小助手立志要不断把坏人的作恶伎俩公之于众,与网络黑势力斗争到...

    腾讯举报中心
  • 有个小哥哥用机器学习帮自己脱单,结果。。。

    滑铁卢大学一位叫 Bai Li 的华裔小哥哥,在 Medium 上分享了自己「如何用 ML 中的逻辑回归方法帮自己找脱单」的神操作。

    HyperAI超神经
  • 程序猿真的觉得写代码比女朋友重要吗?

    IT架构圈
  • 史上最污技术解读,我竟然秒懂了!

    很多同学对热备,冷备,云备了解不深,我科普一下 IT 行业各种备份术语。以后别闹笑话了。

    zhisheng
  • 数据分析视角:咪蒙凭什么写出那么火的文章

           写这篇文章最主要的,是想说明数据和数据分析在工作和生活中的实用性和重要性,顺便说一说我认识的咪蒙。       很早很早之前就听过关于咪蒙的各种...

    沉默的白面书生
  • 【资讯】互联网+改变了什么

    互联网+ 日前,记者在CBD做了一个小调查。100%的人肯定了互联网+为自己的工作和生活带来了莫大的好处,可是这些人当中,又有高达70%的人表示,肯定之余还有不...

    老九君
  • 教女朋友读懂云计算

    结果没想到,一向佛系的女朋友很快被洗脑,天天给我们说"XX云'返利多少倍,某某屌丝靠着“返利XX云”实现了人生逆袭。

    了不起的云计算
  • 一位程序员的十年工作总结

    展望未来,总结过去10年的程序员生涯,给程序员小弟弟小妹妹们的一些总结性忠告 走过的路,回忆起来是那么曲折,把自己的一些心得体会分享给程序员兄弟姐妹们,虽然...

    我就是马云飞
  • 女友长期半夜不回家,窃听了她手机后得知的结果令我崩溃

    我女朋友每天七点就下班了,通常七点半就在家,但是最近这段时间她总是三更半夜才回家,对我态度也极其不耐烦,朋友圈的合照也删了,说有领导看见不太好,可是她以前和我总...

    Python进击者

扫码关注云+社区

领取腾讯云代金券