java-Annotation总结

本文详细探讨了Java注解的使用与实现,包括@Target、@Retention、@Inherited、@Repeatable等元注解的功能,以及如何通过反射获取注解信息。同时,介绍了注解参数支持的数据类型及其默认值设定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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()
}

注解参数的可支持数据类型

  1. 所有基本数据类型(int,float,boolean,byte,double,char,long,short)
  2. String类型
  3. Class类型
  4. enum类型
  5. Annotation类型
  6. 以上所有类型的数组

注解参数可以支持的类型的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 {};  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值