Java注解

Java注解

本文主要讲一下@Target,@Retention,@Constraint,@Documented:

  • 四种注解简介
  • Java8新增ElementType.TYPE_USE,ElementType.TYPE_PARAMETER用法

@Target

注解作用的范围

  • @Target(ElementType.TYPE) //类,接口(包括注解),枚举
  • @Target(ElementType.FIELD) //字段(包括枚举常量)
  • @Target(ElementType.METHOD) //方法
  • @Target(ElementType.PARAMETER) //参数
  • @Target(ElementType.CONSTRUCTOR) //构造函数
  • @Target(ElementType.LOCAL_VARIABLE)//局部变量
  • @Target(ElementType.ANNOTATION_TYPE)//注解
  • @Target(ElementType.PACKAGE) //包
  • @Target(ElementType.TYPE_USE) //类型
  • @Target(ElementType.TYPE_PARAMETER) //类型
  • 查看源码,一目了然
public enum ElementType {
    /** 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
}

@Retention

表示注解可以保存的时间

  • @Retention(RetentionPolicy.SOURCE) //注解保留在源码阶段,被编译器丢弃
  • @Retention(RetentionPolicy.CLASS) // 注解被编译器保存在字节码文件中,在运行时丢弃,默认的保留行为
  • @Retention(RetentionPolicy.RUNTIME)//被虚拟机保存,可用反射机制读取
  • 查看源码,一目了然
public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    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,

    /**
     * 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
     */
    RUNTIME
}

@Constraint

这个是在validation-api-1.1.0.Final.jar包里面的类,如果你要写自定义的校验类,可以引入这个jar包,并且在自定义的校验类里面写你的相关校验,举例如下:

  • 在某接口的入参引入了自定义的注解(其他注解去掉了):
/**投资金额**/
@BigDecimalRange( minPrecision = 0, maxPrecision = 11, scale =2)
private BigDecimal amount;
  • 自定义的注解BigDecimalRange
@Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = BigDecimalValidator.class)
@Documented
public @interface BigDecimalRange 
{
    public Class<?>[] groups() default {};
    public Class<? extends Payload>[] payload() default {};

    long minPrecision() default Long.MIN_VALUE;
    long maxPrecision() default Long.MAX_VALUE;
    int scale() default 0;

}
  • Constraint类源码
@Documented
@Target({ ANNOTATION_TYPE })
@Retention(RUNTIME)
public @interface Constraint {

    /**
     * {@link ConstraintValidator} classes must reference distinct target types
     * for a given {@link ValidationTarget}
     * If two {@code ConstraintValidator}s refer to the same type,
     * an exception will occur.
     * <p/>
     * At most one {@code ConstraintValidator} targeting the array of parameters of
     * methods or constructors (aka cross-parameter) is accepted. If two or more
     * are present, an exception will occur.
     *
     * @return array of (@code ConstraintValidator} classes implementing the constraint
     */
    Class<? extends ConstraintValidator<?, ?>>[] validatedBy();
}
  • 在自定义的注解里的用法如下:
    @Constraint(validatedBy = BigDecimalValidator.class),BigDecimalValidator校验类里面的内容可以自己去写,如对amount范围的校验,最多几位,最少几位,以及小数点后的位数等等

@Documented

说明该注解将被包含在javadoc中

Java8新增TYPE_USE和TYPE_PARAMETER用法

package annotation;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
//ElementType.TYPE_USE是对类型的注解,如下面的泛型,String类型
//ElementType.LOCAL_VARIABLE对局部变量的注解
//ElementType.FIELD字段、枚举的常量
public class TestTypeParam <@TestAnnotation T>{

    List<@TestAnnotation Map<String, String>> l1 = new ArrayList<Map<String, String>>();

    //ElementType.TYPE_USE 对String类型的注解,注意区别下面的test1
    @TestAnnotation String test;

    //ElementType.FIELD对test1的注解
    @TestAnnotation java.lang.String test1;

    public String test1(){
        //ElementType.LOCAL_VARIABLE 对test2的注解
        @TestAnnotation java.lang.String test2 = "hh";
        return test2;
    }



}

反射机制读注解的值

  • 自定义的注解TestAnnotation
package annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE_USE, ElementType.LOCAL_VARIABLE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)

public @interface TestAnnotation {

    public String value() default "{haha,henhao}";
}
  • 用到注解的接口
package interfabstr;

import annotation.TestAnnotation;

public interface TestInterface {

    public static final String STR = "abc";
    String str = "";
    //public static String a; 接口里的变量都是final的,必须初始化

    @TestAnnotation(value=STR)
    public abstract int insert1();

    @TestAnnotation(value=STR)
    public String getString();

    @TestAnnotation(value=STR)
    public void add1();
}
  • 测试类
package interfabstr;

import java.lang.reflect.Method;

import annotation.TestAnnotation;

public class TestMain {

    public static void main(String[] args){
        Class<TestInterface> ti = TestInterface.class;
        Method[] mts = ti.getMethods();
        for(Method mt : mts){
            TestAnnotation ta = mt.getAnnotation(TestAnnotation.class);
            String s = ta.value();
            System.out.println("s: " + s);
        }
    }
}
程序运行结果:
s: abc
s: abc
s: abc

参考:
[1] http://ifeve.com/java-annotation/
[2] http://www.cnblogs.com/Gordon-YangYiBao/archive/2012/08/07/2626340.html

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值