Java注解

1、什么是Java注解

Java Annotation(注解):

从JDK1.5引入

Annotations用于提供有关程序的补充信息,位于源码中的

Annotation以"@"开始

Annotation不会改变已经编译程序的动作

Annotation帮助关联metadata(信息)到程序的元素(用来修饰程序的元素,但不会对被修饰的对象有直接影响,通过其他的工具对标签进行处理(只有通过某种配套的工具才会对注解信息进行访问和处理)):instance variables, constructors, methods, classs等等。

其他工具:编译器、IDE

Annotation are not pure comments,因为它可以改变编译器处理程序的方式,但是它没有起到直接的作用,知识起到一个信息提示的作用。

Annotations的用途:

1.提供信息给编译器/IDE

2. 可用于其他的工具产生额外代码/配置文件等

3.有一些注解可以在程序运行时访问,增加程序的动态性,即在程序运行时,通过反射的方法来访问注解,使得程序可以增加额外的功能。

@SuppressWarnings:压制警告

@Deprecated:丢弃

@Override:其实即使一个Method与父类方法名同名的话,也会覆盖(不用Override注解)

2、Annotations分类

1.Marker Annotations

    这种类型的Annotatiosn的唯一目的是mark一个声明。这些注解不包含任何成员,也不包含任何数据。因此,它作为一个注解的存在就足够了。由于marker interface不包含任何成员,所以简单地确定它是存在还是不存在就够了,@Override就是一个marker Annotation.

@TestAnnotation

2.Single Value Annotations

    该类型注解只包含一个成员,并允许一种指定成员值的shorthand形式。我们只需要在应用注解时为该成员赋值就行,而不需要指定成员的名称。但是,要使用此简写,成员的名称必须是一个值。

@TestAnnotation("testing")

3. Fully Annotations

     该注解包含多个数据成员,名字,值对。

@TestAnnotation(key1 = "1", key2 = "2")

4. Type Annotations

   该注解可以应用于正在使用的类型的任何地方。例如,我们可以注解一个方法的返回值类型。这些申明都是用@Target进行注解

5. Repeating Annotations

    该注解是可以多次应用于单个项的Annotation。要使得Annotation可以重复,必须使用@Repeatable注解,它的值字段制定了container type for the repeatable annotation.container被指定为一个Annotations,它的值字段是可重复注解类型的数组。因此,创建一个repeatable annotation,首先创建一个container注解,然后注解type被指定为一个参数给@Repeatable注解。

3、Predefined/Standard Annotations

    Java定义了7个内置注解(用来修饰Java代码的)。

     1.四个来自于java.lang.annotation:@Retention、@Documented、@Target、@Inherited、Repeatable(元注解:修饰注解的注解)

     2.三个来自于java.lang:@Deprecated、@Override、SuppressWarnings

Annotation1:  @Override

         它是一个只能用于方法的marker annotation.使用@Override注解的方法必须覆盖父类中的方法,如果没有将导致编译错误。它用于确保父类的方法实际被重载,而不是简单的重载。

Annotation2: @Deprecated

        1、该注解是一个marker annotation.它指示改声明已经过时,并且已经被较为新的形式所取代。建议程序员不再使用该类/元素/方法.

        2、javadoc @deprecated tag,当一个元素被deprecated时,应该被使用

        3、@deprecated tag是用用于文档,@Deprecated注解是运行时反射

         4、当两者都使用时,@deprecated tag比@Deprecated 注解有更高的优先级

Annotation3: @SupressWarnings

      该注解用于通知编译器以抑制指定的编译器警告。要抑制的警告以字符串的形式指定。该类型的注解可以用于任何类型的声明(变量/方法/构造函数/类等)。

     Java将Warnings分成两类,一个是deprecated,一个是unchecked,当legacy代码接口和使用泛型的代码unchecked警告会生成

   SupressWarnings("unchecked")、   SupressWarnings("deprecated")、   SupressWarnings("all")、

Annotation4: @Target

      该注解被设计仅用于作为另一个注解的注解,@Target接收一个参数,该参数必须是ElementType枚举中的一个常量。此参数指定可以应用注解的声明的类型。我们可以在@Target注解中指定一个或者多个值。如果要指定多个值,我们必须在大括号分割的列表中指定它们。例如,要指定注释适用于字段和局部变量,可以使用如下:@Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE}) 

 Annotation5: @Retention

      该注解决定了注解被保留的位置以及多长时间(用来修饰其他注解的存在范围),决定被修饰的注解将来保存在什么地方。它有RetentionPolicy三个值:

        SOURCE:注释将被保留在源代码级别(.java文件),并被编译器忽视,也就是不在.class文件

        CLASS:这时默认的注解保留策略,注释将在编译时保留,并被JVM忽略(注解存在于.class文件中,但是不能JVM加载)

        RUNTIME:这些数据将在运行时被保留,注解可以被JVM运行时访问到。通常情况下,可以通过反射技术对注解的字节码进行解析。

Annotation6: @Document

      该注解是一个marker interface,它告诉一个工具要记录一个annotaion.Annotations不包括在"javadoc"注释中。在代码中使用@Documented,使得javadoc这样的工具能够处理解析,并在生成的文档中包含annotation type信息(帮助文档),就是让注解被Javadoc所识别。

Annotation7:@Inherited

      该注解是一个marker annotation,只能够在annotation声明的时候使用。它只影响将用于类声明的Annotation。@Inherited会导致父类的annotation将被子类继承。因此,当向该子类发出对特定注解的请求时,如果该注解不在该子类上面,父类将会被checked。如果父类别注解修饰,并且用@Inherited修饰,然后这个注解将被返回。

import java.lang.annotation.Inherited

@Inherited
public @interface MyAnnotation{

}

@MyAnnotation
public class MySuperClass{

}

public class MySubClass extends MySuperClass{

}

Annotation8: @Repeatable

   -- JDK1.8引入   --表示被修饰的Annotation可以重复应用标注,即这个注解可以重复用在被修饰的对象上

   -- 需要定义注解和容器注解

// 定义注解
public @interface RepeatableAnnotation{
    int a() default 0;
    int b() default 0;
    int c() default 0;
}

// 定义容器注解,用来存储多行重复的注解
public @interface RepeatbleAnnotations{
    RepeatableAnnotation[] value();  // 这里叫做容器注解,存放多个需要定义的注解
}

@RepeatableAnnotation(a=1,b=2,c=3)
@RepeatableAnnotation(a=1,b=2,c=4)
public static void add(int a, int b, int c)  // 这里其实相当于测试add方法,将测试用例写在注解上,可以边写程序,边完成测试用例
{
    if (c != a + b){
        throw new ArithmeticException("Wrong");
    }
}

4、User-defined(custom) annotation

      用户自定义注解可以用来注解程序元素(变量,构造函数,方法等),该注解可以用在声明元素之前

     声明注解:

        [Access Specifier] @interface <AnnotationName> 

        {

               DataType <Method Name>() [default value];  // 这里其实是属性,只不过定义成方法的形式(只是没有参数),这时Java规定

               DataType <Method Name>() [default value];

        }

       1、方法的返回值有:8 primitive type(char/short/int/float/double/long/byte/boolean)、String、enum、Class、注解类型、前面组成的数组

目录

1、什么是Java注解

2、Annotations分类

3、Predefined/Standard Annotations

4、User-defined(custom) annotation


       针对三种不同的加载策略有不同的解析方法

     1.RetentionPolicy.RUNTIME:注解在class文件中,被JVM加载,可以反射解析注解

Class.getAnnotations();  // 获取这个类的头部有哪些Annotation修饰
Class.isAnnotation(); //这个类是否有注解修饰

 // Method, Field, Constructor都有相应的API来获取上述成员

     2. RetentionPolicy.CLASS:注解在class中,但是JVM没有加载,所以在程序运行时,我们是访问不到这部分的注解字节码的

       这部分注解只能采用字节码工具进行特殊处理

             如ASM工具, https://asm.ow2.io/

     3. RetentionPolicy.SOURCE:注解在java文件中,,编译之后,不在class文件中,也不会被JVM加载,所以在程序运行中,访问不到这一部分源码级别的注解。

      -- 只有在源码级别上进行注解处理

      -- Java提供了注解处理器来解析带注解的源码,产生新文件

      -- 注解处理器继承自AbstractProcessor,重写process方法

      -- javac (Java编译工具:将.java编译成.class文件),编译的时候加上一个 -processor参数,然后把我们自己写的注解处理器写上去(可以写多个注解处理器,这些注解处理器会依次处理浙西源码级别的注解)javac -processor Processor1 Processor,.., sourceJavaFile

     -- 编译器定位源文件的注解,然后依次启动注解处理器依次执行处理。如果某个注解处理器产生新的源文件(什么叫做新的源文件?因为注解处理器在读取源文件里面的源码级别的注解的时候,它会读取这些注解,然后会有新的文件出来,因为老的Java文件,是不能修改的),那么将重复执行这个处理过程

   -- 注解处理器只能产生新的文件,不会修改已有的源文件,会读取这部分源码注解,然后,产生一个新文件,把新文件和老文件放在一起,继续编译,直到没有新的文件产生。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值