要创建一个自定义注解,可以按照以下步骤进行:
使用 @interface 关键字定义注解
使用 @interface 关键字定义一个注解,例如:
public @interface MyAnnotation {
// ...
}
为注解添加属性
为注解添加需要的属性,例如:
public @interface MyAnnotation {
String name();
int age() default 18;
}
在上述代码中,MyAnnotation注解包含了两个属性,分别是name和age。其中,name属性是必选的,age属性是可选的,如果不指定默认值,则默认为18。
添加元注解
为注解添加需要的元注解,例如@Target、@Retention、@Inherited等。例如:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
String name();
int age() default 18;
}
在上述代码中,@Target注解指定了注解的作用目标为类、接口或枚举,@Retention注解指定了注解的生命周期为运行时,@Inherited注解指定了该注解可以被子类继承。
使用注解
在需要使用注解的地方,使用@MyAnnotation的方式添加注解,例如:
@MyAnnotation(name = "Tom", age = 20)
public class MyClass {
// ...
}
在上述代码中,使用@MyAnnotation注解标记了一个类MyClass,并指定了name和age属性的值。
读取注解信息
在程序运行时,可以使用反射机制读取注解信息。例如:
MyAnnotation annotation = MyClass.class.getAnnotation(MyAnnotation.class);
String name = annotation.name();
int age = annotation.age();
在上述代码中,使用MyClass.class.getAnnotation(MyAnnotation.class)方法获取MyClass类上的MyAnnotation注解,并读取了其中的name和age属性的值。
需要注意的是,自定义注解的命名需要符合Java标识符的命名规范,通常使用驼峰式命名法。同时,自定义注解的属性必须是常量,即使用final修饰的变量,或者是基本数据类型、字符串、枚举类型、注解类型或以上类型的数组类型。
@Retention(RetentionPolicy.RUNTIME)是一个注解元注解,用于指定注解的生命周期。其中,RetentionPolicy.RUNTIME表示该注解在程序运行时仍然可用。
具体来说,@Retention注解可以用于定义自定义注解时,指定该注解的生命周期。
Java中定义了三种注解生命周期,分别是:
RetentionPolicy.SOURCE:表示该注解只在源代码中可用,编译后不会写入class文件。
RetentionPolicy.CLASS:表示该注解在编译时可用,但不会写入class文件,只在编译阶段保留。
RetentionPolicy.RUNTIME:表示该注解在运行时仍然可用,可以被JVM读取,并且可以通过反射机制获取注解信息。
通常情况下,自定义注解需要使用RetentionPolicy.RUNTIME生命周期,以便在程序运行时使用反射机制获取注解信息,实现不同的功能。
@Target(ElementType.TYPE)是一个注解元注解,用于指定注解的作用目标。其中,ElementType.TYPE表示该注解可以用于类、接口、枚举或注解类型上。
具体来说,@Target注解可以用于定义自定义注解时,指定该注解可以用于哪些程序元素上。例如,如果一个注解只能用于类上,则可以在注解定义中添加@Target(ElementType.TYPE)注解,表示该注解只能用于类、接口、枚举或注解类型上,不能用于方法、字段或其他程序元素上。
@Inherited是一个注解元注解,用于指定注解是否可以被子类继承。如果一个注解被@Inherited注解修饰,则表示该注解可以被子类继承,否则不能被子类继承。
具体来说,@Inherited注解可以用于定义自定义注解时,指定该注解是否可以被子类继承。例如,如果一个注解需要被多个子类继承使用,则可以在注解定义中添加@Inherited注解,表示该注解可以被子类继承使用。
需要注意的是,@Inherited注解只对类注解有效,对方法注解和字段注解无效。这是因为方法和字段是程序元素,而不是类,它们无法被继承。因此,如果一个注解需要对方法或字段生效,需要在注解定义中添加@Target(ElementType.METHOD)或@Target(ElementType.FIELD)注解,表示该注解只能用于方法或字段上。
需要注意的是,@Inherited注解只对直接继承的子类有效,对间接继承的子类无效。例如,如果一个注解被父类注解,而子类继承了子类,则该注解对子类无效。这是因为,注解的继承是通过类继承关系实现的,只有直接继承关系才能够被识别。