@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation interface
* can be applied to.
* @return an array of the kinds of elements an annotation interface
* can be applied to
*/
ElementType[] value();
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
public @interface Deprecated {
String since() default "";
boolean forRemoval() default false;
}
[修饰符列表] @interface 注解类型名{
类型 属性() [defauult 值];
}
// 样例
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String name() default "gdb";
String[] phoneNumbers() default {};
}
1.编写自己的注解:
package annotation1;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String name() default "gdb";
String[] phoneNumbers() default {};
}
2.在类上使用自己的注解:
package annotation1;
@MyAnnotation(name = "zhangsan", phoneNumbers = {"123456", "654321"})
public class MyAnnotationTest {
}
package annotation1;
import java.util.Arrays;
public class ReflectAnnotation {
public static void main(String[] args) throws Exception {
//获取类
Class<?> c = Class.forName("annotation1.MyAnnotationTest");
//判断类上面是否有 @MyAnnotation
if (c.isAnnotationPresent(MyAnnotation.class)){
//获取注解对象
MyAnnotation myAnnotation = (MyAnnotation)c.getAnnotation(MyAnnotation.class);
//获取注解对象的属性和调用接口没有区别
System.out.println(myAnnotation.name() + ", " + Arrays.toString(myAnnotation.phoneNumbers()));
}
//判断 Date 类上面是否有 @MyAnnotation 这个注解。
Class<?> s = Class.forName("java.lang.String");
System.out.println(s.isAnnotationPresent(MyAnnotation.class));
}
}
注解在程序当中等同于一种标记,如果这个元素上有这个注解怎么办,没有这个注解怎么办。
应用场景:假设有这样一个注解,叫做 @Id,这个注解只能出现在类上面,当这个类上有这个注解的时候,要求这个类中必须有一个 int 类型的 id 属性。如果没有这个属性就报异常。如果有这个属性就正常执行。
package annotation1;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Id {
}
package annotation1;
public class NotHasIdException extends RuntimeException{
public NotHasIdException() {
}
public NotHasIdException(String message) {
super(message);
}
}
package annotation1;
@Id
public class IdAnnotationTest {
int id;
}
package annotation1;
import java.lang.reflect.Field;
public class ReflectAnnotation {
public static void main(String[] args) throws Exception {
//获取类
Class<?> c = Class.forName("annotation1.IdAnnotationTest");
//判断类上面是否有 @Id 注解
if (c.isAnnotationPresent(Id.class)){
//当一个类上面有 @Id 注解的时候,要求类中必须存在 int 类型的id属性。
//如果没有int类型的id属性则报异常。
//获取类的所有属性
Field[] fields = c.getDeclaredFields();
boolean isOK = false;
for(Field field : fields){
if("id".equals(field.getName()) && "int".equals(field.getType().getSimpleName())){
isOK = true;
break;
}
}
//判断是否合法
if (!isOK)
throw new NotHasIdException("被@Id注解标注的类没有int类型的id属性!!!");
}
}
}