每天进步一点点

  • 一、认识注解
  • 二、JDK内置的三个注解
  • 1.@Override
  • 2.@Deprecated
  • 3.@SuppressWarnings
  • 三、自定义注解
  • 1.如何自定义注解
  • 2.使用自定义注解
  • 四、反射与注解
  • 五、元注解
  • 1.@Retention
  • 2.@Target
  • 3.@Documented
  • 4.@Inherited


一、认识注解

JDK1.5开始,Java增加了对元数据(即类的组成单元数据)的支持,也就是(Annotation)注解,他是代码里做的特殊标记,这些标记可以在编译,类加载,运行时在不改变原有逻辑的情况下被读取,并执行相应的处理,通过使用Annotation,程序员可以在源文件中嵌入一些补充的信息。代码分析工具,开发工具和部署工具可以通过这些补充信息进行验证或者进行部署,Annotation类似于修饰符一样被使用,可以用于包、类、构造方法、方法、成员变量、参数、局部变量的声明。

PS:Annotation是一个接口(Java.lang.Annotation接口)

二、JDK内置的三个注解

在JDK1.5之后,在系统中提供了三个Annotation,分别是:@Override,@Deprecated,@SuppressWarnings

1.@Override

表示当前方法定义将重写父类中的方法,如果不小心拼写错误,或者方法名对不上重写的方法,编译器就会发出错误提示。

重写Object中的toString方法,只要重写方法有问题,就有错误提示

java 注解 限制输入类型 java注解报错_开发语言

2.@Deprecated

用于表示所修饰的元素(类,方法,构造器,属性等)已过时,但是该方法也能使用

java 注解 限制输入类型 java注解报错_intellij-idea_02


该方法也能被正常使用

java 注解 限制输入类型 java注解报错_java 注解 限制输入类型_03

3.@SuppressWarnings

抑制编译器警告

  • @SuppressWarnings("unchecked"):未检查的转化,如集合没有指定类型
  • @SuppressWarnings("unused"):未使用的变量
  • @SuppressWarnings("resource"):有泛型未指定类型
  • @SuppressWarnings("path"):在类路径,原文件路径中不存在的路径
  • @SuppressWarnings("deprecation"):使用了某些不赞成使用的类的方法
  • @SuppressWarnings("fallthrough"):switch语句中执行到底没有break关键字
  • @SuppressWarnings("serial"):某类实现Serializable但是没有定义SerialVersionUID这个需要但是不必须的字段
  • @SuppressWarnings("rawtypes"):没有传递带有泛型的参数
  • @SuppressWarnings("all"):全部类型的警告

java 注解 限制输入类型 java注解报错_java 注解 限制输入类型_04

三、自定义注解

1.如何自定义注解

自定义注解使用很少,一般情况下都是用现成的注解。

注解应用需要三个步骤:

  • 编写注解
  • 在类上应用注解
  • 对应用了注解的类进行反射操作的类

java 注解 限制输入类型 java注解报错_javase_05


java 注解 限制输入类型 java注解报错_java_06


定义的注解的声明使用的关键字:@interface,跟接口没有一点关系

这value是属性还是方法?
答案:看上去是无参数方法,实际上理解为一个成员变量,一个属性
无参数方法名字–>成员变量的名字
无参数方法的返回值–>成员变量的类型
这个参数叫配置参数

无参数方法的类型:基本数据类型(八种),String,枚举,注解类型,还可以是以上类型对应的数组。

2.使用自定义注解

使用注解的话,如果你定义了配置参数,就必须给配置参数进行赋值操作

java 注解 限制输入类型 java注解报错_java_07


如果只有一个参数,并且这个参数的名字为value的话,那么value=可以省略不写

java 注解 限制输入类型 java注解报错_javase_08


如果你给配置参数设置默认的值了,那么使用的时候可以无需传值

java 注解 限制输入类型 java注解报错_javase_09


一个注解的内部是可以不定义配置参数的,内部没有定义配置参数的注解–>可以叫做标记

java 注解 限制输入类型 java注解报错_java 注解 限制输入类型_10


内部定义配置参数的注解–>元数据

java 注解 限制输入类型 java注解报错_java_11

四、反射与注解

一个Annotation真正起作用,必须结合反射机制,在反射包(java.lang.reflect.AccessibleObject)中提供了以下的操作方法:

  • public boolean isAnnotationPresent(Class<? extends Annotation>):判断是否指定的Annotation
  • public Annotation[] getAnnotations():得到全部的Annotation
public class Test {
    public static void main(String[] args)  {
        //反射来处理注解
        Class<Person> personClass = Person.class;
        //获取类变量上的指定注解
        MyAnnotation annotation = personClass.getAnnotation(MyAnnotation.class);
        //获取注解的变量值
        String[] value = annotation.value();
    }
}

五、元注解

元注解是用于修饰其它注解的注解

java 注解 限制输入类型 java注解报错_开发语言_12

JDK1.5提供了四种元注解:Retention, Target, Documented, Inherited

1.@Retention

@Retention:用于修饰注解,用于指定修饰的那个注解的生命周期,@Rentention包含一个RetentionPolicy枚举类型的成员变量,使用@Rentention时必须为该value成员变量指定值

  • RetentionPolicy.SOURCE:在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释,在.class文件中不会保留注解信息
  • RetentionPolicy.CLASS:在class文件中有效(即class保留),保留在.class文件中,但是当运行Java程序时,他就不会继续加载了,不会保留在内存中,JVM不会保留注解。如果注解没有加Retention元注解,那么相当于默认的注解就是这种状态。
  • RetentionPolicy.RUNTIME:在运行时有效(即运行时保留),当运行 Java程序时,JVM会保留注释,加载在内存中了,那么程序可以通过反射获取该注释。

2.@Target

@Target注解表示的是一个Annotation的使用范围,例如:之前定义的MyAnnotation可以在任意的位置上使用

java 注解 限制输入类型 java注解报错_javase_13

@Target({TYPE,CONSTRUCTOR,METHOD})
	public @interface MyAnnotation4 {
}

java 注解 限制输入类型 java注解报错_intellij-idea_14

3.@Documented

用于指定被该元注解修饰的注解类将被javadoc工具提取成文档。默认情况下,javadoc是 不包括注解的,但是加上了这个注解生成的文档中就会带着注解了

如果:Documented注解修饰了Deprecated注解

java 注解 限制输入类型 java注解报错_intellij-idea_15


那么Deprecated注解就会在javadoc提取的时候,提取到API中

java 注解 限制输入类型 java注解报错_开发语言_16

4.@Inherited

被他修饰的Annotation将具有继承性,如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解

使用时允许被其子类所继承

@Inherited
@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation{
    public String name();
    public Striing info();
}