java-annotation
java.lang.annotation.Annotation
Annotation主类,任何@xxx 在通过getAnnotation()得到的接口类是Annotation
,通过方法可以获取到Annotation的类,注意不是通过getClass得到
Class<? extends Annotation> annotationType();
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@FSConstraint(validatedBy =FSNotEmptyContraintValidator.class)
@interface notNull{
String message();
}
public class User{
@NotNull(message="name can not be empty")
private String name;
@NotNull(message="age can not be empty")
private int age;
}
obj=new User();
Field[] fs=obj.getClass().getDeclaredFields();
for(Field f:fs){//遍历获取到User对象上的所有的Field
Annotation[] ans=f.getAnnotations(); //拿到Field的所有的annotaion,也就是@NotNull
for(Annotation an:ans){
//对于 NotNull 这个Annotation需要到注解的注解
//例如NotNull的注解@FSConstraint(validatedBy =FSNotEmptyContraintValidator.class)
//使用下面
Annotation[] ansofAn=an.annotationType().getAnnotations();
//不要是用an.getClass().getAnnotations();
}
}
java.lang.annotation.Target
表明了annotation 可以放在哪些类型上,和ElementType
进行配合使用java.lang.annotation.ElementType
指明Annotation可以放在哪些类型上
如下
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
java.lang.annotation.Inherited
父类中的某个annotation如果有@Inherited, 则这个annotation会被子类查到,注意父类不可以是接口
例子说明如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited //这里加了@Inherited
public @interface Component {
}
@Component
public class Service {
}
public class AService extends Service {
}
public static void main(String[] args) {
AService aService=new AService();
System.out.println(aService.getClass().getAnnotation(Component.class));
}
AService 继承了Service,而Service有注解Component,并且Component里有@Inherited,这里可以打印出来,如果去掉@Inherited,则打印结果为空
java.lang.annotation.Retention
表明了注解保留的方式,和RetentionPolicy
配合一起使用java.lang.annotation.RetentionPolicy
如下
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*只是在source上保留,complier编译的时候丢弃
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
* 编译成class会保修,但在运行时候会丢弃
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
* 运行的时候也会保留,如果是上面的2种,是不能通过aService.getClass().getAnnotation(Component.class) 获取到的
*/
RUNTIME
}
java.lang.annotation.Repeatable
表明annotation
是否能被重复的使用
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Repeatable(Components.class)
public @interface Component {
String name();
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Components {
Component[] value();
}
使用注解方式1
@Component("a")
@Component("A")
public class AService extends Service {
}
使用注解方式2
@Components({@Component(name="b"),@Component(name="B")})
public class BService extends Service {
}
注解参数可以支持的类型
@Interface Foo{
<类型> value()
}
注解参数的可支持数据类型:
- 所有基本数据类型(int,float,boolean,byte,double,char,long,short)
- String类型
- Class类型
- enum类型
- Annotation类型
- 以上所有类型的数组
注解参数可以支持的类型的default值
上述的类型可以支持default值如下
public @interface Foo {
<类型> value() default <类型的default值>;
}
对于可支持数据类型的1-4和5的默认值都很好做,但对于Annotation的默认值缺不好做
例如:
有个注解
public @interface Config {
boolean ignoreUnknown() default false;
int steps() default 1;
}
public @interface Foo {
Config value() default <default值>;
}
这里Config的default值不能是null,{},可以写成
public @interface Foo {
Config[] value() default {};
}