女朋友:我要自己的注释,你教教我!月:诶?你为什么突然想要自己的注释?女友:关你什么事!“拆散”!月亮:不要,不要,不要!我来教!moon:看看我的宝~你spring学的不错,那我先带你看看Autowired~@Target({ElementType.CONSTRUCTOR,ElementType.METHOD,ElementType.PARAMETER,ElementType.FIELD,ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceAutowired{/***Declareswhethertheannotateddependencyisrequired.*
Defaultsto{@codetrue}.*/booleanrequired()defaulttrue;}moon:参见“Autowired”发现,“类名这个类的称为Autowired”,所以你知道为什么要发布@Autowired吗?女朋友:哦哦哦哦哦哦哦!我明白!原来“类名就是注解名”!月亮:我女朋友很聪明!我们再看一下,它有一些特别之处,类符号是class,“注解符号是@interface”。闺蜜:嗯.....那还不错,你继续moon:我们看一下@Autowired上面的三个注解,它们的作用是什么,我们先看第一个“@Documented”/***表示thatannotationswithatypearetobedocumentedbyjavadoc*andsimilartoolsbydefault.Thistypeshouldbeusedtoannotatethe*declarationsoftypeswhoseannotationsaffecttheuseofannotated*elementsbytheirclients.Ifatypedeclarationisannotatedwith*Documented,itsannotationsbecomepartofthepublicAPI*oftheannotatedelements.**@authorJoshuaBloch*@since1.5*/@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public@interfaceDocumented{}moon:看,我们发现第一个是@Documented,我们看看它的注解是什么?moon:通过自己强大的英文阅读能力,发现“@Documented注解其实只是用来生成文档的”,而你可以用javadoc生成api文档,所以这个注解肯定“不重要”闺蜜:呸!你显然依赖翻译!渣男!月亮:嘿,我们看下一个!“@保留”!向上。/***Indicateshowlongannotationswiththeannotatedtypeareto*beretained.IfnoRetentionannotationispresenton*anannotationtypedeclaration,theretentionpolicydefaultsto*{@codeRetentionPolicy.CLASS}.**
ARetentionmeta-annotationhaseffectonlyifthe*meta-annotatedtypeisuseddirectlyforannotation.Ithasno*effectifthemeta-annotatedtypeisusedasamembertypein*anotherannotationtype.**@authorJoshuaBloch*@since1.5*@jls9.6.3.2@Retention*/@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public@interfaceRetention{/***Returnstheretentionpolicy.*@returnstheretentionpolicy*/RetentionPolicyvalue();}月亮:再次通过我强大的英文阅读能力,这个note是什么意思?moon:其实就是告诉你note的“生命周期”有多长,而这个生命周期的定义是在“RetentionPolicy里面”,我们来看看这个RetentionPolicy是什么?publicenumRetentionPolicy{/***注释由编译器*记录在类文件中,但不需要由VMat运行时保留。这是默认值*havior.*/CLASS,/***Annotationsaretoberecordedintheclassfilebythecompilerand*retainedbytheVMatruntime,sotheymaybereadreflectively.**@seejava.lang.reflect.AnnotatedElement*/RUNTIME}女朋友:我对这个很熟悉!“SOURCE是作用于源码,CLASS是作用于编译后的源码,RUNTIME是作用于运行时”!这不就是Java的三种状态吗!moon:你学会回答我的宝了!!!!闺蜜:哼!快点继续!!moon:哈哈哈,好吧,说说最后一个注解“@Target”@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public@interfaceTarget{/***Returnsanarrayofthekindsofelementsanannotationtype*canbeappliedto.*@returnanarrayofthekindsofelementsanannotationtype*canbeappliedto*/ElementType[]value();}moon:这个注解的作用其实很简单,“它告诉你这个注解可以应用于哪些范围被贴在”,你知道什么作用域女友:嗯……有类,有方法,有成员变量……moon:哈哈哈哈,我不知道!!女友:哼!!“分手”!!!!moon:Don'tDon'tdon'tdon't,听我说!这个作用域其实是隐藏在“ElementType[]”数组中的,走吧进去看看吧!publicenumElementType{/**Class,interface(includingannotationtype),orenumdeclaration关注公众号:moonchattechnology,获取更多有趣的文章*/TYPE,/**Fielddeclaration(includesenumconstants)*/FIELD,/**Methoddeclaration*/METHOD,/**形式参数声明*/PARAMETER,/**构造函数声明*/CONSTRUCTOR,/**局部变量声明*/LOCAL_VARIABLE,/**注解类型声明*/ANNOTATION_TYPE,/**封装声明*/PACKAGE,/***类型参数声明**@since1.8*/TYPE_PARAMETER,/***Useofatype**@since1.8*/TYPE_USE}moon:总共有“10个范围”所以当你确定你的注解的范围时,你粘贴@Target(scope),那就是它!闺蜜:哦,我明白了,那我有个问题,“我想让我的子类继承这个注解怎么办?”?月亮:!!!!!!!这就是我接下来要讲的!!「@Inherited」!!也是java中的四大元注解之一(还有刚刚提到的@Target、@Retention、@Documented这三个)!它的作用是“让子类也可以继承父类的注解”,那么你知道怎么用吗?女友:Min...moon:举个例子吧!只是练习它!闺蜜:哼!moon:先写一个注解类@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public@interfaceMyAnnotation{/***sayIloveyou(defaulttrue)*/booleansayILoveYou()defaulttrue;}moon:这个注解很简单,“只能应用到方法上,运行时才可以实现,有个syaILoveYou方法,默认为true!”注释了我们的@MyAnnotation表达我的诚意开始测试!publicclassMain{publicstaticvoidmain(String[]args){try{//获取Me的Class对象Meme=newMe();Classclazz=me.getClass();//获取这个对象的sayLoveYou方法上的Info类型注解MyAnnotationmyAnnotation=clazz.getMethod("sayLoveYou",null).getDeclaredAnnotation(MyAnnotation.class);if(myAnnotation.sayILoveYou()){System.out.println("我爱你");}else{System.out.println("我不'tloveyou");}}catch(Exceptione){e.printStackTrace();}}}moon:我们先拿到了Me对象,然后拿到了MyAnnotation注解。如果myAnnotation.sayILoveYou()为真,它会输出“我爱你”!如果为假,则输出“我不爱你”!女友:你不爱我,“我们分手吧”我爱你!因为我们默认为truemoon:我们修改了注解的默认值,结果是ENlovesyouforme(充满求生欲望)publicclassMe{@MyAnnotation(sayILoveYou=false)publicvoidsayLoveYou(){System.out.println("表达我的诚意”);}}闺蜜:哼~月亮:我们再试试@Inherited注解,修改MyAnnotation,“添加@Inherited”,添加“添加ElementType.TYPE并使其可用作用于类”@Retention(RetentionPolicy.RUNTIME)@Target({Ele,mentType.METHOD,ElementType.TYPE})@Inheritedpublic@interfaceMyAnnotation{/***sayIloveyou(defaulttrue)*/booleansayILoveYou()defaulttrue;}moon:Me这个类是在类@MyAnnotationpublicclassMe{publicvoidsayLoveYou(){System.out.println("Express我的诚意");}}月亮:那如果我们有孩子publicclassChildextendsMe{}女朋友:我不会嫁给你!){try{//获取孩子的Class对象Childchild=newChild();Classclazz=child.getClass();//获取对象sayLoveYou方法上的Info类型注解MyAnnotationmyAnnotation=(MyAnnotation)clazz.getAnnotation(MyAnnotation.class);if(myAnnotation.sayILoveYou()){System.out.println("我爱你");}else{System.out.println("我不爱你");}}catch(Exceptione){e.printStackTrace();}}moon:"此时子对象没有@MyAnnotation注解,它只是继承了我,但是由于我们在Me类上贴了@MyAnnotation注解,并且有了@Inherited注解,孩子也有这个注解的功能,所以运行结果一定是我爱你!”月亮:现在你知道了吧!注释就是这么简单!闺蜜:哼,你还有用,我不需要你了,走吧月亮:好老板!(终于教出来了,我又活下来了)你一共分了多少次手,你都数过了吗?