元注解、系统内置标准注解、自定义注解概念区别

注解

Annotations是一种元数据,其作用在于提供程序本身以外的一些数据信息,也就是说Annotation他不会属于程序代码本身,不参与逻辑运算,故而不会对原程序代码的操作产生直接的影响。

1.Java与元数据

元数据是关于数据的数据。在编程语言上下文中,元数据是添加到程序元素如方法、字段、类和包上的额外信息。

Java 元数据(Annotation)是 J2SE 5.0 (研发历时近三年,于2004年9月30日正式发布,代号为“Tiger”)新增加的功能之一,它在JSR-175规范中有详细定义。该机制允许在 Java 代码中添加自定义注释,并允许通过反射(reflection),以编程方式访问元数据注释。通过提供为程序元素附加额外数据的标准方法,元数据功能具有简化和改进许多应用程序开发领域的潜在能力,其中包括配置管理、框架实现和代码生成。

元数据的作用:

用于创建文档
跟踪代码中的依赖性
执行编译时检查
代码分析

元数据还可用于协助程序元素与框架或者EJB、EMF 和 TestNG这样的工具之间的通信。EJB 3.0就广泛地应用了Java元数据,通过元数据来实现声明性请求企业服务,依赖性以及资源注入,消除了严格的EJB组件模型约束,并且取代了复杂的XML配置文件
元数据甚至使我们可以不用修改核心语言,就能够在 Java 语言中添加新功能,使核心语言成为一种开放式语言。在纯面向对象的语言中实现AOP就是使用元数据进行语言扩展的一个很好的例子。AspectWerkz、JBoss AOP以及AspectJ5 使用元数据将类的语义转换为一个aspect、将数据字段转换为一个pointcut、将方法转换为一个advice,等等。

2.简单的运用场景

@Override
public String toString() {
    return"This is String Representation of current object.";
}

上面的代码中,我重写了toString()方法并使用了@Override注解。但是,即使我不使用@Override注解标记代码,程序也能够正常执行。

@Override告诉编译器这个方法是一个重写方法(描述方法的元数据),如果父类中不存在该方法,编译器便会报错,提示该方法没有重写父类中的方法。如果我不小心拼写错误,例如将toString()写成了toStrring(){double r},而且我也没有使用@Override注解,那程序依然能编译运行。但运行结果会和我期望的大不相同。

3.定义

四种元注解,专门注解其他的注解:

@Documented –注解是否将包含在Java中,表示是否将注解信息添加在文档中
@Retention –什么时候使用该注解
@Target –注解用于什么地方
@Inherited – 是否允许子类继承该注解

3.1 Retention

@Retention定义了该Annotation被保留的时间长短,可以为编译器提供而外信息,以便于检测错误,抑制警告等,譬如@Override、@SuppressWarnings等这类注解就是用于标识,可以用作一些检验CLASS 编译时动态处理。

一般这类注解会在编译的时候,根据注解标识,动态生成一些类或者生成一些xml都可以,在运行时期,这类注解是没有的,也就是在类加载的时候丢弃。会依靠动态生成的类做一些操作,因为没有反射,效率和直接调用方法没什么区别
RUNTIME 运行时动态处理。

3.2 Target

@Target说明了Annotation所修饰的对象范围:Annotation可被用于

  1. packages

  2. types(类、接口、枚举、Annotation类型)

  3. 类型成员(方法、构造方法、成员变量、枚举值)

  4. 方法参数和本地变量(如循环变量、catch参数)

3.3 Inherited

表示该注解类型被自动继承。

如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

如果用户在当前类中查询这个元注解类型并且当前类的声明中不包含这个元注解类型,那么也将自动查询当前类的父类是否存在Inherited元注解,这个动作将被重复执行知道这个标注类型被找到,或者是查询到顶层的父类

3.4 内部实现
  1. 在定义注解时,不能继承其他的注解或接口。

  2. @interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。

    1. 方法的名称就是参数的名称

    2. 返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)

    3. 可以通过default来声明参数的默认值。

      自定义注解例子
      public class Test3 {
      
          private int age;
      
          @MyAnnotation3("aaa")
          public int getAge() {
              return age;
          }
      
      }
      
      
      @Target(value={ElementType.METHOD})
      @Retention(value = RetentionPolicy.RUNTIME)
      @interface MyAnnotation3{
      
          String[] value(); 
      
      }
      
      @Target(value={ElementType.METHOD})
      @Retention(value = RetentionPolicy.RUNTIME)
      @interface MyAnnotation2{
      
          String name() default "";
          int age() default 0;
          int id() default -1; // String indexOf("abc")   -1, 找不到,不存在
      
          String[] schools();
      
      }
      
  3. 注解参数的可支持数据类型:

  4. 所有基本数据类型(int,float,boolean,byte,double,char,long,short)

  5. String类型

  6. Class类型

  7. Annotation类型

  8. 以上所有类型的数组

    Annotation类型里面的参数该怎么设定:

第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;   
第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;  
第三,如果只有一个参数成员,最好把参数名称设为”value”,后加小括号.例:下面的例子FruitName注解就只有一个参数成员。
(注解元素必须有确定的值,要么在定义注解的默认值中指定,要么在使用注解时指定,非基本类型的注解元素的值不可为null。
因此, 使用空字符串或0作为默认值是一种常用的做法。
当然,这个约束使得处理器很难表现一个元素的存在或缺失的状态,因为每个注解的声明中,所有元素都存在,并且都具有相应的值,为了绕开这个约束,我们只能定义一些特殊的值(-1,”“),例如空字符串或者负数,一次表示某个元素不存在,在定义注解时,这已经成为一个习惯用法)

系统内置标准注解

@Override:用于修饰此方法覆盖了父类的方法;
@Deprecated:用于修饰已经过时的方法;
@SuppressWarnnings:用于通知java编译器禁止特定的编译警告

Override

@Override,限定重写父类方法:

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

Deprecated

同样Deprecated也是一个标记注解。

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

SuppressWarnnings

@SuppressWarnings 被用于有选择的关闭编译器对类、方法、成员变量、变量初始化的警告。在java5.0,sun提供的javac编译器为我们提供了-Xlint选项来使编译器对合法的程序代码提出警告,此种警告从某种程度上代表了程序错误。例如当我们使用一个generic collection类而又没有提供它的类型时,编译器将提示出”unchecked warning”的警告。通常当这种情况发生时,我们就需要查找引起警告的代码。如果它真的表示错误,我们就需要纠正它。例如如果警告信息表明我们代码中的switch语句没有覆盖所有可能的case,那么我们就应增加一个默认的case来避免这种警告。
 
  有时我们无法避免这种警告,在调用的方法前增加@SuppressWarnings修饰,告诉编译器停止对此方法的警告。
    annotation语法允许在annotation名后跟括号,括号中是使用逗号分割的name=value对用于为annotation的成员赋值。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值