write:2022-3-29
update:2022
注解机制
有没有办法让运行中的Java程序能读取一个Java类的注解信息呢?从JDK5开始,提供了一种灵活的注解机制,它允许Java程序在运行时读取类的注解信息。
运用注解机制主要包含以下步骤:
(1)自定义Annotation注解类型。
(2)在类的源代码中引用注解类型。
(3)在程序中运用反射机制读取类的注解信息。
自定义Annotation注解类型
-
注解类型也属于一种Java类型,它用“@interface”关键字来声明。eg:public @interface MyAnnotation{} //声明注解类
注意与接口关键字区别:定义接口:public interface MyIFC{…} //声明接口 -
当MyAnnotation注解类的类体为空“{}”,不包含任何成员,这样的注解称为标识型注解(Marked Annotation)。
此外,在声明注解类型时,可以定义一些成员。
public @interface MyAnnotation{
String value();
} -
“default”关键字:
下面的代码定义了包含两个成员的MyAnnotation类:
public @interface MyAnnotation{
String value() default “默认构造方法”;
Class type() default void.class;
}
以上“default”关键字用于为成员设定默认值。例如type成员的默认值为“void.class”。 -
在定义注解类型时,还可以引用JDK内置的一些注解类型来进行相关的限定。
@Target注解:用来指定当前注解所适用的目标。(有可能是类,构造方法,成员变量等等)
@Rentention注解:指定当前注解的有效范围。(有以下三种)
@Documented注解:标识性注解。表示注解类型包含的信息会被加入到JavaDoc文档中。 -
eg:
先定义三个注解类型:
package Annotation;
import java.lang.annotation.*;
@Documented
@Target(ElementType.TYPE)//使用与java类型
@Retention(RetentionPolicy.RUNTIME)//有效范围是运行时
public @interface AuthorAnnotation {
String name();
String company();
}
package Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.CONSTRUCTOR) //适用于构造方法
@Retention(RetentionPolicy.RUNTIME) //有效范围是运行时
public @interface ConstructorAnnotation {
String value() default "默认构造方法"; //value字段的默认值是:"默认构造方法"
}
package Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//适用于成员变量、成员方法和参数
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME) //有效范围是运行时
public @interface CommonAnnotation {
Class type() default void.class;
String description();
}
在类的源代码中引用注解
前面定义的注解根据其引用目标和范围等,引用到类中
Person类:
package Annotation;
@AuthorAnnotation(name = "Tom",company = "ABC Company")
public class Person {
@CommonAnnotation(type = String.class,description = "姓名")
private String name;
@CommonAnnotation(type=int.class,description="年龄")
private int age;
@ConstructorAnnotation
public Person(){
this("unknown",0);
}
@ConstructorAnnotation("带参数的构造方法")
public Person( //注解构造方法的参数
@CommonAnnotation(type=String.class,description="姓名")String name,
@CommonAnnotation(type=int.class,description="年龄")int age) {
this.name = name;
this.age = age;
}
@CommonAnnotation(type=String.class,description="获得姓名")
public String getName() {
return name;
}
@CommonAnnotation(description="设置姓名")
public void setName(@CommonAnnotation(type=String.class,description="姓名")String name) {
this.name = name;
}
@CommonAnnotation(type=int.class,description="获得年龄")
public int getAge() {
return age;
}
@CommonAnnotation(description="设置年龄")
public void setAge(
@CommonAnnotation(type=int.class,description="年龄")int age){
this.age=age;
}
}
在程序中运用反射机制读取类的注解信息
课堂小结
思考题
2.以下哪些是JDK内置的标识型注解?
a) @Target
b) @Documented
c) @Override
d) @Rentention
[答案] b,c