注解:
定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
注释:给程序员阅读的
注解:给JVM看的
作用分类:
- 编写文档:通过代码里标识的注解生成文档【例如,生成文档doc文档】
- 代码分析:通过代码里标识的注解对代码进行分析【例如,注解的反射】
- 编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【例如,Override】
常见注解
- @author:用来标识作者名
- @version:用于标识对象的版本号,适用范围:文件、类、方法。
- @Override :用来修饰方法声明,告诉编译器该方法是重写父类中的方法,如果父类不存在该方法,则编译失败。
自定义注解:使用关键字@interface
注意:定义注解使用的也是.java文件。编译生成的也是.class文件
定义格式
元注解
public @interface 注解名称{
属性列表;
}
例如:
package com.ccc.demo05Annotation;
public @interface MyAnnotation01 {
}
- 注解本质上就是一个接口,该接口默认继承Annotation接口
public interface MyAnno extends java.lang.annotation.Annotation {}
定义一个含有属性的注解
-
属性的作用
- 可以让用户在使用注解时传递参数,让注解的功能更加强大。注解中的属性我们可以看成是抽象方法,但是有默认值
-
属性的格式
public @interface MyAnnotation02 {
修饰符 数据类型 属性名();
修饰符 数据类型 属性名() default 默认值;
}
修饰符:固定使用public abstract,可以省略不写;但是建议写出,增强语句的阅读性
- 属性定义示例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;
}
-
属性适用的数据类型
- 八种基本数据类型(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
}
自定义注解的使用:
注解的使用范围:
- 可以使用在包上,类上,接口上,成员变量,成员方法,构造方法,局部变量上,方法参数前
- 但是同名的注解一个位置,只能使用一次
- 同一个位置,不同名的注解都可以使用
使用格式:
@注解名(属性名=属性值,属性名=属性值,属性名=属性值,属性名=属性值,属性名=属性值,…)
- 没有属性的注解@属性名可以直接使用
- 有属性的注解,我们必须使用键值对的方式为注解中的所有属性都赋值,注解才能使用
a.有默认值的属性,可以不用赋值
b.多个属性赋值,需要使用逗号分隔开
c.属性的类型如果是一个数组。那么赋值需要使用一个{ }把所有的值包裹起来。数组如果只有一个值,可以省略{ }
例如:arr={“aaa”,“bbb”,“ccc”}
arr=“aaa”
d.注解中如果只有一个属性,并且属性的名字叫value,那么赋值时可以省略key,直接写value值
例如:value=10 ——>10
特殊属性value
- 当注解中只有一个属性且名称是value,在使用注解时给value属性赋值可以直接给属性值,无论value是单值元素还是数组类型。
- 如果注解中除了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;
}
}