一 注解简介
java提供了一种原程序中关联任何信息和任何元数据的途径和方法。(从JDK1.5之后)
二 java中的常见注解
@Override
java.lang.Override是一个标记类型注解,它被用作标注方法。它说明了被标注的方法重载了父类的方法,起到了断言的作用。如果我们使用了这种注解在一个没有覆盖父类方法的方法时,java编译器将以一个编译错误来警示。
@Deprecated
Deprecated也是一种标记类型注解。标记一个过时的方法,同时编译器会发出警告。
@SuppressWarnings
当用Deprecated标记一个方法是一个过时的方法,不想编译器发出警告,可以使用@SuppressWarnings("unchecked")注解
三 元注解
元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。(自定义注解时,需要使用元注解)
1.@Target –注解用于什么地方
@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。可用的ElementType参数包括:
● ElementType.CONSTRUCTOR:用于描述构造器
● ElementType.FIELD:成员变量、对象、属性(包括enum实例)
● ElementType.LOCAL_VARIABLE:用于描述局部变量
● ElementType.METHOD:用于描述方法
● ElementType.PACKAGE:用于描述包
● ElementType.PARAMETER:用于描述参数
● ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明
2. @Retention –什么时候使用该注解
● RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。只在源文件中有效,编译出的.class文件中没有。
● RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。只在.class文件中有效。
● RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
3.@Documented–一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中。
4.@Inherited – 定义该注释和子类的关系
如果使用@Inherited注解的类被它的一个子类继承,那么这个注解也用于它的子类。
四 自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。
在定义注解时,不能继承其他的注解或接口。
@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
参数成员只能用public或默认(default)这两个访问权修饰。
参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组.
要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation对象。
如果只有一个参数成员,最好把参数名称设为"value"。
自定义注解格式:
public @interface 注解名 {定义体}
五 自定义注解例子
StudentAge .java- 注解学生年龄类
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StudentAge {
int value() default -1;
}
StudentName .java-注解学生名称类
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StudentName {
enum Name {STUDENTONE, STUDENTTWO, STUDENTTHREE}
Name getStudentName() default Name.STUDENTONE;
}
School .java-注解学校类
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface School {
int id() default -1;
String name() default "";
String address() default "";
}
AnnotationUtil .java-注解处理器
package com.yyw.annotation;
import java.lang.reflect.Field;
public class AnnotationUtil {
public static void getStudentInfo(Class<?> clazz) {
String studentAgeInfo = "学生年龄:";
String studentNameInfo = "学生名称:";
String schoolInfo = "学校信息:";
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(StudentAge.class)) {
StudentAge age = (StudentAge) field.getAnnotation(StudentAge.class);
studentAgeInfo = studentAgeInfo + age.value();
System.out.println(studentAgeInfo);
} else if (field.isAnnotationPresent(StudentName.class)) {
StudentName name = (StudentName) field.getAnnotation(StudentName.class);
studentNameInfo = studentNameInfo + name.getStudentName().toString();
System.out.println(studentNameInfo);
} else if (field.isAnnotationPresent(School.class)) {
School school = (School) field.getAnnotation(School.class);
schoolInfo = " 学校编号:" + school.id() + " 学校名称:" + school.name() + "学校地址:" + school.address();
System.out.println(schoolInfo);
}
}
}
}
AnnotationTestBean .java-测试用例
public class AnnotationTestBean {
@StudentAge(value = 20)
private int studentAge;
@StudentName(getStudentName = StudentName.Name.STUDENTONE)
private String studentName;
@School(id = 1, name = "北京大学", address = "北京")
private String school;
public int getStudentAge() {
return studentAge;
}
public void setStudentAge(int studentAge) {
this.studentAge = studentAge;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
}
AnnotationTestBean .java-主方法
public class AnnotationTest {
public static void main(String[] args) {
AnnotationUtil.getStudentInfo(AnnotationTestBean.class);
}
}
输出
学生年龄:20
学生名称:STUDENTONE
学校编号:1 学校名称:北京大学学校地址:北京