注解就是个什么东西?

最近在学习JAVA 注解这块总是一知半解、模模糊糊的,特地抽出时间对注解知识做个全面梳理,希望对其他初级学习者能有所帮助,文章转载并手动试验代码。

什么是注解

  • Annotation(注解)就是java提供了一种元程序中的元素关联任何信息和着元数据的途径和方法。Annotation(注解)是一个接口,程序可以通过反射来获取程序元素的Annotation对象,然后通过Annotation对象来获取注解里面的元数据。
  • Annotation(注解)是JDK5.0及以后版本引入的。它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。从某些方面看,annotation就像修饰符一样被使用,并应用于包、类 型、构造方法、方法、成员变量、参数、本地变量的声明中。这些信息被存储在Annotation的“name=value”结构对中。
  • Annotation的成员在Annotation类型中以无参数的方法的形式被声明。其方法名和返回值定义了该成员的名字和类型。在此有一个特定的默认语法:允许声明任何Annotation成员的默认值:一个Annotation可以将name=value对作为没有定义默认值的Annotation成员的值,当然也可以使用name=value对来覆盖其它成员默认值。这一点有些近似类的继承特性,父类的构造函数可以作为子类的默认构造函数,但是也可以被子类覆盖。
  • Annotation能被用来为某个程序元素(类、方法、成员变量等)关联任何的信息。需要注意的是,这里存在着一个基本的规则:Annotation不能影响程序代码的执行,无论增加、删除 Annotation,代码都始终如一的执行。另外,尽管一些annotation通过java的反射api方法在运行时被访问,而java语言解释器在工作时忽略了这些annotation。正是由于java虚拟机忽略了Annotation,导致了annotation类型在代码中是“不起作用”的; 只有通过某种配套的工具才会对annotation类型中的信息进行访问和处理。本文中将涵盖标准的Annotation和meta-annotation类型,陪伴这些annotation类型的工具是java编译器(当然要以某种特殊的方式处理它们)。

什么是metadata(元数据)

元数据从metadata一词译来,就是“关于数据的数据”的意思。
  元数据的功能作用有很多,比如:你可能用过Javadoc的注释自动生成文档。这就是元数据功能的一种。总的来说,元数据可以用来创建文档,跟踪代码的依赖性,执行编译时格式检查,代替已有的配置文件。如果要对于元数据的作用进行分类,目前还没有明确的定义,不过我们可以根据它所起的作用,大致可分为三类:
    1. 编写文档:通过代码里标识的元数据生成文档
    2. 代码分析:通过代码里标识的元数据对代码进行分析
    3. 编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查
  在Java中元数据以标签的形式存在于Java代码中,元数据标签的存在并不影响程序代码的编译和执行,它只是被用来生成其它的文件或针在运行时知道被运行代码的描述信息。
  综上所述:
    第一,元数据以标签的形式存在于Java代码中。
    第二,元数据描述的信息是类型安全的,即元数据内部的字段都是有明确类型的。
    第三,元数据需要编译器之外的工具额外的处理用来生成其它的程序部件。
    第四,元数据可以只存在于Java源代码级别,也可以存在于编译之后的Class文件内部。

Annotation和Annotation类型:

  • Annotation:
    Annotation使用了在java5.0所带来的新语法,它的行为十分类似public、final这样的修饰符。每个Annotation具有一个名字和成员个数>=0。每个Annotation的成员具有被称为name=value对的名字和值(就像javabean一样),name=value装载了Annotation的信息。
  • Annotation类型:
    Annotation类型定义了Annotation的名字、类型、成员默认值。一个Annotation类型可以说是一个特殊的java接口,它的成员变量是受限制的,而声明Annotation类型时需要使用新语法。当我们通过java反射api访问Annotation时,返回值将是一个实现了该 annotation类型接口的对象,通过访问这个对象我们能方便的访问到其Annotation成员。后面的章节将提到在java5.0的 java.lang包里包含的3个标准Annotation类型。

注解的分类:

  • 根据注解参数的个数,我们可以将注解分为三类:
        1.标记注解:一个没有成员定义的Annotation类型被称为标记注解。这种Annotation类型仅使用自身的存在与否来为我们提供信息。比如后面的系统注解@Override;
        2.单值注解
        3.完整注解

  • 根据注解使用方法和用途,我们可以将Annotation分为三类:
        1.JDK内置系统注解
        2.元注解
        3.自定义注解

系统内置标准注解:

注解的语法比较简单,除了@符号的使用外,他基本与Java固有的语法一致,JavaSE中内置三个标准注解,定义在java.lang中:
    @Override:用于修饰此方法覆盖了父类的方法;
    @Deprecated:用于修饰已经过时的方法;
    @SuppressWarnnings:用于通知java编译器禁止特定的编译警告。

下面我们依次看看三个内置标准注解的作用和使用场景。

@Override , 限定重写父类方法

@Override 是一个标记注解类型,它被用作标注方法。它说明了被标注的方法重载了父类的方法,起到了断言的作用。如果我们使用了这种Annotation在一个没有覆盖父类方法的方法时,java编译器将以一个编译错误来警示。这个annotaton常常在我们试图覆盖父类方法而确又写错了方法名时发挥威力。使用方法极其简单:在使用此annotation时只要在被修饰的方法前面加上@Override即可。下面的代码是一个使用@Override修饰一个企图重载父类的say方法,拼写错误导致编译无法通过
在这里插入图片描述

@Deprecated

同 样Deprecated也是一个标记注解。当一个类型或者类型成员使用@Deprecated修饰的话,编译器将不鼓励使用这个被标注的程序元素。而且这种修饰具有一定的 “延续性”:如果我们在代码中通过继承或者覆盖的方式使用了这个过时的类型或者成员,虽然继承或者覆盖后的类型或者成员并不是被声明为 @Deprecated,但编译器仍然要报警。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

SuppressWarnings 一直编译器警告

在这里插入图片描述
@SuppressWarnings注解的常见参数值:

1.deprecation:使用了不赞成使用的类或方法时的警告;

2.unchecked:执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型;

3.fallthrough:当 Switch 程序块直接通往下一种情况而没有 Break 时的警告;

4.path:在类路径、源文件路径等中有不存在的路径时的警告;

5.serial:当在可序列化的类上缺少 serialVersionUID 定义时的警告;

6.finally:任何 finally 子句不能正常完成时的警告;

7.unused:代码中的变量或方法没有被使用产生的警告;

8.rawtypes:使用泛型时没有指定类型的警告;

9.all:关于以上所有情况的警告。

10.更多关键字

元注解

元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:

  1. @Target

  2. @Retention

  3. @Documented

  4. @Inherited

  • @Target
    作用:描述该注解修饰的范围,可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。
    取值(ElementType):
    1.CONSTRUCTOR:用于描述构造器
    2.FIELD:用于描述域
    3.LOCAL_VARIABLE:用于描述局部变量
    4.METHOD:用于描述方法
    5.PACKAGE:用于描述包
    6.PARAMETER:用于描述参数
    7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

  • @Retention
    作用:描述该注解的生命周期,表示在什么编译级别上保存该注解的信息。Annotation被保留的时间有长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。

取值(RetentionPoicy):

1.SOURCE:在源文件中有效(即源文件保留)

2.CLASS:在class文件中有效(即class保留)
    
3.RUNTIME:在运行时有效(即运行时保留)

  • @Documented
    @Documented Annotation的作用是在生成javadoc文档的时候将该Annotation也写入到文档中。

  • @Inherited
    作用:@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

自定义注解

使用@interface自定义注解,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。

  • 定义注解格式
    public @interface 注解名 {定义体}

  • 注解参数的可支持数据类型:

  1. 所有基本数据类型(int,float,boolean,byte,double,char,long,short)
  2. String类型
  3. Class类型
  4. enum类型
  5. Annotation类型
  6. 以上所有类型的数组
  • 参数定义要点
  1. 只能用public或默认(default)这两个访问权修饰;
  2. 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组;
  3. 如果只有一个参数成员,建议参数名称设为value();
  4. 注解元素必须有确定的值,要么在定义注解的默认值中指定,要么在使用注解时指定,非基本类型的注解元素的值不可为null。因此, 使用空字符串或负数作为默认值是一种常用的做法

转自 https://www.jianshu.com/p/4068da3c8d3d

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值