注解(一)的定义、自定义注解及使用

注解:

定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

注释:给程序员阅读的

注解:给JVM看的

作用分类

  • 编写文档:通过代码里标识的注解生成文档【例如,生成文档doc文档】
  • 代码分析:通过代码里标识的注解对代码进行分析【例如,注解的反射】
  • 编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【例如,Override】

常见注解

  1. @author:用来标识作者名
  2. @version:用于标识对象的版本号,适用范围:文件、类、方法。
  3. @Override :用来修饰方法声明,告诉编译器该方法是重写父类中的方法,如果父类不存在该方法,则编译失败。

自定义注解:使用关键字@interface

注意:定义注解使用的也是.java文件。编译生成的也是.class文件

定义格式

元注解
public @interface 注解名称{
	属性列表;
}

例如:

package com.ccc.demo05Annotation;

public @interface MyAnnotation01 {
}
  • 注解本质上就是一个接口,该接口默认继承Annotation接口
public interface MyAnno extends java.lang.annotation.Annotation {}

定义一个含有属性的注解

  1. 属性的作用

    • 可以让用户在使用注解时传递参数,让注解的功能更加强大。注解中的属性我们可以看成是抽象方法,但是有默认值
  2. 属性的格式

public @interface MyAnnotation02 {
	修饰符 数据类型 属性名();
	修饰符 数据类型 属性名() default 默认值;
}

修饰符:固定使用public abstract,可以省略不写;但是建议写出,增强语句的阅读性

  1. 属性定义示例1
public @interface Student {
     String name(); // 姓名
     public abstract int age() default 18; // 年龄
     public abstract String gender() default "男"; // 性别
} 
   // 该注解就有了三个属性:name,age,gender

示例2

public @interface MyAnnotation02 {
    //定义一个int类型的属性
    public abstract int a();
    //定义一个double类型的属性,添加默认值5.5
    double d() default 5.5;
    //定义一个String类型的数组
    public abstract String[] arr();

    //以下类型作为了解
    
    //定义一个反射类型的属性
    public abstract Class clazz();
    
    //定义一个注解类型的属性(MyAnnotation01为本章中第一个案例)
    public abstract MyAnnotation01 my01();
    
    //定义一个枚举类型的属性
    public abstract Color c() default  Color.RED;
}
  1. 属性适用的数据类型

    • 八种基本数据类型(int,float,boolean,byte,double,char,long,short)
    • String类型,Class类型(即反射类型),枚举类型,注解类型
    • 以上所有类型的一维数组

枚举简单举例:

package com.itheima.demo05Annotation;

/*
    枚举中的属性,通过枚举的名字可以直接使用(类似于静态)  Color.RED
    相当于以下代码
        public static final Color c1 = new RED();
        public static final Color c1 = new GREEN();
 */
public enum Color {
    RED,GREEN
}

自定义注解的使用:

注解的使用范围:

  1. 可以使用在包上,类上,接口上,成员变量,成员方法,构造方法,局部变量上,方法参数前
  2. 但是同名的注解一个位置,只能使用一次
  3. 同一个位置,不同名的注解都可以使用

使用格式:

@注解名(属性名=属性值,属性名=属性值,属性名=属性值,属性名=属性值,属性名=属性值,…)

  1. 没有属性的注解@属性名可以直接使用
  2. 有属性的注解,我们必须使用键值对的方式为注解中的所有属性都赋值,注解才能使用
       a.有默认值的属性,可以不用赋值
       b.多个属性赋值,需要使用逗号分隔开
       c.属性的类型如果是一个数组。那么赋值需要使用一个{ }把所有的值包裹起来。数组如果只有一个值,可以省略{ }
             例如:arr={“aaa”,“bbb”,“ccc”}
                        arr=“aaa”
       d.注解中如果只有一个属性,并且属性的名字叫value,那么赋值时可以省略key,直接写value值
             例如:value=10 ——>10

特殊属性value

  1. 当注解中只有一个属性且名称是value,在使用注解时给value属性赋值可以直接给属性值,无论value是单值元素还是数组类型。
  2. 如果注解中除了value属性还有其他属性,且至少有一个属性没有默认值,则在使用注解给属性赋值时,value属性名不能省略。

使用注意事项

  • 如果属性有默认值,则使用注解的时候,这个属性可以不用赋值。
  • 如果属性没有默认值,那么在使用注解时一定要给属性赋值。

下面举例说明:

定义只有一个属性的注解,名字叫value
package com.itheima.demo05Annotation;

public @interface MyAnnotation03 {
    public abstract String value();
}
使用前面定义过的注解
package com.ccc.demo05Annotation;

@MyAnnotation01
@MyAnnotation02(a = 10,arr = {"aaa","bbb","ccc"})
public class UseMyAnnotation {
    @MyAnnotation01
    @MyAnnotation03(value = "hello")
    private String name;

    @MyAnnotation02(a = 100,d = 8.8,arr="aaa")
    private int age;

    @MyAnnotation01
    @MyAnnotation03("你好")
    public UseMyAnnotation(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @MyAnnotation01
    public String getName() {
        return name;
    }

    @MyAnnotation02(a = 10,arr = "aaa")
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_45083975/article/details/91980403