Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >女朋友说想要自己的注解,我又活下来了!!!

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

作者头像
moon聊技术
发布于 2021-08-20 02:21:37
发布于 2021-08-20 02:21:37
53900
代码可运行
举报
文章被收录于专栏:moon聊技术moon聊技术
运行总次数:0
代码可运行

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

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

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

moon:别别别别别!我教!

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


代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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」

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 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」!这个可有的说头了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 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 到底是什么?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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」

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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[]」 这个数组当中,我们进去看下!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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:我们先写个注解类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    /**
     * 说我爱你(默认true)
     */
    boolean sayILoveYou() default true;
}

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

女朋友:yue~快说

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Me {
    @MyAnnotation
    public void sayLoveYou(){
        System.out.println("表达一下我的真心");
    }
}

女朋友:yue~

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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爱你了(满满的求生欲)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Me {
    @MyAnnotation(sayILoveYou=false)
    public void sayLoveYou(){
        System.out.println("表达一下我的真心");
    }
}

女朋友:哼~

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Retention(RetentionPolicy.RUNTIME)
@Target({Ele,mentType.METHOD,ElementType.TYPE})
@Inherited
public @interface MyAnnotation {
    /**
     * 说我爱你(默认true)
     */
    boolean sayILoveYou() default true;
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@MyAnnotation
public class Me {
    public void sayLoveYou(){
        System.out.println("表达一下我的真心");
    }
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Child extends Me{
}

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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:好的老板!(终于教会了,我又活下来了)

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 moon聊技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
面试系列之-JAVA注解剖析(JAVA基础)
(01) 1个Annotation 和 1个RetentionPolicy关联。可以理解为:每1个Annotation对象,都会有唯一的RetentionPolicy属性。
用户4283147
2023/08/21
1490
面试系列之-JAVA注解剖析(JAVA基础)
深入理解 Spring 中的各种注解,总有一款是你需要的!
spring的bean容器相关的注解,先后有:@Required, @Autowired, @PostConstruct, @PreDestory
Java小咖秀
2021/04/20
5170
深入理解 Spring 中的各种注解,总有一款是你需要的!
java自定义注解
现在我们就有了一个自定义的注解 @MyAnnotation。但是现在这个注解还不能添加在任何地方,需要继续修改。
何白白
2019/06/28
1.1K0
自定义Android注解Part1:注解变量
对于Android注解,或多或少都有一点接触,但相信大多数人都是在使用其它依赖库的时候接触的。因为有些库如果你想使用它就必须使用它所提供的注解。例如:ButterKnife、Dagger2、Room等等。
Rouse
2019/07/16
4690
自定义Android注解Part1:注解变量
Java 注解
java.lang.annotation.RetentionPolicy.java
沪上队长
2018/04/25
2.8K4
Eventbus3代码分析(二):注解入门
我们扯淡到java的知识,最好是先参考别人的文章,或者看官方的 自己能力有限,所以只是简单扯扯,有兴趣,最好自己看官方的解释
dodo_lihao
2018/09/12
3280
Eventbus3代码分析(二):注解入门
秒懂,Java 注解 (Annotation)你可以这样用
它们是Target、Retention、Documented和Inherited。
lyb-geek
2018/07/26
8730
秒懂,Java 注解 (Annotation)你可以这样用
Java注解学习
java中我们经常要遇到各种注解,这些注解极大的方便了我们的开发。我们也就知道注解的原理好像也是一种接口和标志什么什么的,本质上说我们对JDK注解并不了解。所以理解JDK注解是我们java开发的基础。在spring中就大面积的使用了注解。所以理解这些基础的注解对于后期的开发都特别重要。
写一点笔记
2020/08/25
4260
Java注解学习
Spring系列第十七讲 深入理解Java注解及Spring对注解的增强(上)
代码中注释大家都熟悉吧,注释是给开发者看的,可以提升代码的可读性和可维护性,但是对于java编译器和虚拟机来说是没有意义的,编译之后的字节码文件中是没有注释信息的;而注解和注释有点类似,唯一的区别就是注释是给人看的,而注解是给编译器和虚拟机看的,编译器和虚拟机在运行的过程中可以获取注解信息,然后可以根据这些注解的信息做各种想做的事情。比如:大家对@Override应该比较熟悉,就是一个注解,加在方法上,标注当前方法重写了父类的方法,当编译器编译代码的时候,会对@Override标注的方法进行验证,验证其父类中是否也有同样签名的方法,否则报错,通过这个注解是不是增强了代码的安全性。
易兮科技
2020/11/24
1.2K0
Spring系列第十七讲 深入理解Java注解及Spring对注解的增强(上)
java进阶之自定义注解
博客: https://shuaijia.github.io/
蜻蜓队长
2018/08/03
4680
java进阶之自定义注解
java自定义注解的使用和基本原理「建议收藏」
在web开发中,权限控制非常重要,所以有些接口会限制必须登录之后才能访问,但是个别接口并没有这种限制。一种方式是把需要过滤的接口或者方法配置在文件中,每次请求时在拦截器中根据请求的路径与配置文件中的对比过滤。其实还有另外一种方式就是通过注解方式。
全栈程序员站长
2022/07/30
5000
java自定义注解的使用和基本原理「建议收藏」
你说啥什么?注解你还不会?
元注解就是注解自定义注解的注解。可能有点饶,一会看例子就明白了,直白点就是给你自定义的注解上一定要加的注解。
手撕代码八百里
2020/10/26
4550
spring自定义注解实现(spring里面的注解)
1.SOURCE:在源文件中生效,仅存在java文件中,class文件将会去除注解。
全栈程序员站长
2022/07/30
7820
spring自定义注解实现(spring里面的注解)
注解的那些事儿(二)| 如何自定义注解
自定义注解是自己写框架的必备技能,使用注解能极大地提升开发效率,因此自定义注解是一个高级开发者必备的技能。
陈树义
2018/08/01
7400
注解的那些事儿(二)| 如何自定义注解
【刨根问底】java注解--下
@Retention只能修饰注解定义,用于指定被修饰的注解可以保留多长时间,@Retention包含了一个RetentionPolicy类的value变量,所以使用此注解时必须为该value变量赋值。源码如下:
田维常
2019/07/16
2890
【刨根问底】java注解--下
android注解
包 java.lang.annotation 中包含所有定义自定义注解所需用到的原注解和接口。 如接口 java.lang.annotation.Annotation 是所有注解继承的接口,并且是自动继承,不需要定义时指定,类似于所有类都自动继承Object。 该包同时定义了四个元注解,Documented,Inherited,Target(作用范围,方法,属性,构造方法等),Retention(生命范围,源代码,class,runtime)。
提莫队长
2019/02/21
5290
【Java 注解】自定义注解 ( 元注解 )
@Target 注解用于说明该注解作用位置 , ElementType.METHOD 表示该注解用于标注 方法 ; 注解的作用位置 : 包 , 类 , 成员变量 , 方法 , 方法参数 , 局部变量 , 6 个作用位置 ;
韩曙亮
2023/03/29
1.2K0
【Java 注解】自定义注解 ( 元注解 )
Spring注解
自动按照类型注入。当ioc容器中有且只有一个类型匹配时可以直接注入成功。当有超过一个匹配时,则使用变量名称(写在方法上就是方法名称)作为bean的id,在符合类型的bean中再次匹配,能匹配上就可以注入成功。当匹配不上时,是否报错要看required属性的取值。
酒楼
2023/11/13
1970
Java学习笔记——新特性-注解
从 JDK 5.0 开始, Java 增加了对元数据(MetaData) 的支持, 也就是 Annotation(注解)。
梦飞
2022/06/23
2270
Java 注解(Annotation)
从Java5.0版发布以来,5.0平台提供了一个正式的annoatation功能:允许开发者定义、使用自己的annotation类型。此功能由一个定义annotation声明的语法,读取annotation的API,一个使用annotation修饰的class文件,一个annotation处理工具(apt)组成。
全栈程序员站长
2022/09/08
4370
相关推荐
面试系列之-JAVA注解剖析(JAVA基础)
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验