Java注解是一个非常重要的知识点。掌握Java注解有利于学习Java开发框架的底层实现。@mikechenJava注解定义Java注解,也称为Java注解,是JDK5引入的新特性,注解(也称为元数据)。Java注解提供了一种安全的类注解机制,用于将任何信息或元数据(metadata)与程序元素(类、方法、成员变量等)相关联。Java注解是附加在代码上的一些元信息,用于在编译运行时解析和使用一些工具,起到描述和配置的作用。Java注解应用1.生成文档这是java提供的最普遍也是最早的注解;2.编译时检查格式,比如方法前的@Override,如果你的方法没有重写父类的方法,那么编译时就可以检查;3、跟踪代码依赖关系,实现替换配置文件的功能。比较常见的是spring2.5开始的基于注解的配置,用来减少配置;4、在反射的Class、Method、Field等函数中,有很多与Annotation相关的接口,可以在反射中解析使用。Java注解的分类1、Java自带的标准注解包括@Override、@Deprecated、@SuppressWarnings等,使用这些注解后,编译器会对其进行检查。2.元注解元注解是用来定义注解的注解,包括@Retention、@Target、@Inherited、@Documented、@Repeatable等。\meta注解也是Java自带的标准注解,但是它是用于修饰注解,比较特殊。3.自定义注解用户可以根据自己的需要自定义注解。Java标准注解JDK内置了以下注解:1.@Override如果你试图用@Override来标记一个实际上并没有覆盖父类的方法,java编译器会发出警告。classParent{publicvoidtest(){}}classChildextendsParent{/***释放以下注释,编译时会发出警告*//*@Overridepublicvoidtest(){}*/}2.Deprecated@Deprecated用于表示修改的类或类成员、类方法已被弃用、过时,不推荐使用。@DeprecatedclassTestClass{//dosomething}3.@SuppressWarnings@SuppressWarnings用于关闭编译类、方法和成员时产生的特定警告。1)抑制单一类型警告@SuppressWarnings("unchecked")publicvoidaddItems(Stringitem){@SuppressWarnings("rawtypes")Listitems=newArrayList();项目.添加(项目);}2)抑制@SuppressWarnings(value={"unchecked","rawtypes"})的多种类型警告publicvoidaddItems(Stringitem){Listitems=newArrayList();项目.添加(项目);}3)抑制所有类型的警告@SuppressWarnings("all")publicvoidaddItems(Stringitem){Listitems=newArrayList();项目.添加(项目);}@SuppressWarnings注解的常用参数值简单说明:4.@FunctionalInterface@FunctionalInterface用于表示修饰的接口为函数式接口,在JDK8中引入。@FunctionalInterfacepublicinterfaceUserService{voidgetUser(LonguserId);//默认方法,可以使用多个默认方法publicdefaultvoidsetUser(){}//静态方法publicstaticvoidsaveUser(){}//重写对象方法中的equalspublicbooleanequals(Objectobj);}函数式接口(FunctionalInterface)是一种只有一个抽象方法的接口,但可以有多个非抽象方法。Java元注解元注解由javaAPI提供,用于修改注解。它们通常用在注解的定义中:1.@Retention@Retention用于定义注解在哪个级别可用,在源代码中(SOURCE),在类文件中(CLASS),还是在运行时(RUNTIME).@Retention源码:@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public@interfaceRetention{RetentionPolicyvalue();}publicenumRetentionPolicy{//该注解类型的信息只会记录在源文件,在编译时会被编译器丢弃,也就是说//编译后的类信息中不会保存它SOURCE,//编译器会在类文件中记录注解,但不会加载进入JVM。如果一个注解语句没有指定作用域,系统//默认值为ClassCLASS,//注解信息会保留在源文件和class文件中,执行时会加载到JavaJVM中,所以可以读取反射性地选择。RUNTIME}RetentionPolicy是一个枚举类型,定义了@Retention修饰的注解支持的保留级别:\@Target(ElementType.METHOD)@Retention(RetentionPolicy.SOURCE)//注解信息只能出现在源文件中public@interfaceOverride{}@Documented@Retention(RetentionPolicy.RUNTIME)//执行时出现注解信息@Target(value={CONSTRUCTOR,FIELD,LOCAL_VARIABLE,METHOD,PACKAGE,PARAMETER,TYPE})public@interfaceDeprecated{}@Target({TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})@Retention(RetentionPolicy.SOURCE)//注解信息出现在源文件中public@interfaceSuppressWarnings{String[]value();}2.@Documented@Documented:保留注解时生成文档信息,并为类提供辅助说明publicStringsetFuncName()默认“setField”;publicStringgetFuncName()默认“getField”;publicbooleandefaultDBValue()defaultfalse;}3.@Target@Target:用于描述注解的使用范围(即所描述的注解可以用在什么地方)@Target源码:@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public@interfaceTarget{ElementType[]value();}ElementType是一个枚举类型,定义了@Target修饰的注解可以应用作用域:\4.@Inherited@Inherited:表示子类可以继承父类中的注解,表示自动继承注解类型。如果注解类型声明中有@Inherited元注解,则该注解修饰的类的所有子类都会继承该注解。@Inheritedpublic@interfaceGreeting{publicenumFontColor{BULE,RED,GREEN};字符串名称();FontColorfontColor()defaultFontColor.GREEN;}5.@Repeatable@Repeatable表示注解可以重复使用。当我们需要复用一个注解,想用同一个注解来表达所有的形式时,可以使用@Repeatable注解。\以Spring@Scheduled为例:@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceSchedules{Scheduled[]value();}@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Repeatable(Schedules.class)public@interfaceScheduled{//...}自定义注解当我们理解内置注解、元注解和反射接口时获取注解之后,我们就可以开始自定义注解了。创建自定义注解和创建接口类似,但是注解的interface关键字需要以@符号开头,我们可以为注解声明方法。自定义注解格式://meta-annotationpublic@interfaceannotationname{//attributelist}先来看看注解的例子:1.创建自定义注解/***自定义注解示例**@authormikechen*/@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@Inheritedpublic@interfaceHelloAnnotation{Stringvalue();}2.使用自定义注解/***使用自定义注解**@authormikechen*/publicclassHelloAnnotationClient{@HelloAnnotation(value="SimplecustomAnnotationexample")publicvoidsayHello(){System.out.println("InsidesayHellomethod..");}}3。测试自定义注解/***自定义注解测试**@authormikechen*/publicclassHelloAnnotationTest{publicstaticvoidmain(String[]args)throwsException{HelloAnnotationClienthelloAnnotationClient=newHelloAnnotationClient();方法method=helloAnnotationClient.getClass().getMethod("sayHello");if(method.isAnnotationPresent(HelloAnnotation.class)){HelloAnnotationhelloAnnotation=method.getAnnotation(HelloAnnotation.class);//获取自定义注解的值System.out.println("Value:"+helloAnnotation.value());//调用sayHello方法method.invoke(helloAnnotationClient);}}}以上作者简介陈锐|mikechen,10年+大厂架构经验,《BAT架构技术500期》系列文章作者,分享十余年BAT架构经验和面试心得!更多技术文章看mikechen的互联网架构合集JavaConcurrency|JVM|MySQL|Spring|Redis|Distributed|HighConcurrency|架构师关注“mikechen的互联网架构”公众号,回复【架构】领取本人原创《300 期 + BAT 架构技术系列与 1000 + 大厂面试题答案》
