java注解(一)

注解有2个很基础的属性:

  • @Target(作用对象)
  • @Retention(保留策略)

在这里插入图片描述

@Retention保留策略:

  • @Retention(RetentionPolicy.SOURCE):保留到源码阶段,在编译成class文件时丢弃,不会保留到class文件中;需要注意的是,在编译器处理期间源码注解还存在,编译器处理完之后就没有该注解信息了;
  • @Retention(RetentionPolicy.CLASS):保留到编译阶段,会被vm丢弃
  • @Retention(RetentionPolicy.RUNTIME):保留到运行时;一般自定义注解,会选择使用RUNTIME配合反射使用;

@Target作用对象:

  • @Target(ElementType.TYPE) 作用于:class,interface,enum,annotation(常用)
  • @Target(ElementType.FIELD) 作用于:字段
  • @Target(ElementType.METHOD)作用于:方法
  • @Target(ElementType.PARAMETER)作用于:方法的参数
  • @Target(ElementType.CONSTRUCTOR)作用于:构造方法
  • @Target(ElementType.LOCAL_VARIABLE)作用于:方法内的局部变量
  • @Target(ElementType.ANNOTATION_TYPE)作用于:作用于注解类annotation
  • @Target(ElementType.PACKAGE) 作用于包
  • @Target(ElementType.TYPE_PARAMETER) 作用于类型泛型(jdk1.8加入)
  • @Target(ElementType.TYPE_USE) 类型使用.可以用于标注任意类型(JDK1.8加入)

有了上面2个基础的注解我们就可以自定义一个自己的注解类了;


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnno {
    /**
     *功能:
     * true:字段值不能为null,如果是int类型,就不能为0
     * false:字段值可以为null
     * @return
     */

    boolean NOTNULL() default false;//default 默认值,如果不添加default,在使用这个注解时就必须给NOTNULL设置值;



}

       只有这个注解,其实没有任何意义,这个时候注解没有功能;想要有功能就必须解析这个注解类;在RUNTIME时,可以通过反射获取到字段上面的注解类,来制定我们想要的功能;其实在编译阶段也可以解析注解,lombok注解的Retention是SOURCE,在编译期间就对注解进行了处理;(source/class这篇博客就是讲解如何在编译器处理注解;)

public class ParseMyAnno {


	/**
	*只处理了String类型和int类型的变量;
	*
	*/
	
    public void parse(Class c,Object object ) throws IllegalAccessException {
        Field[] fields = c.getFields();
        for (Field field : fields) {
            if(field.getAnnotation(MyAnno.class)!= null){
                boolean notnull = field.getAnnotation(MyAnno.class).NOTNULL();//获取到NOTNULL的值;
                Object value = field.get(object);
                if(notnull){
                    String typeName = field.getGenericType().getTypeName();
                    System.out.println(typeName);

                    if((typeName.equals("java.lang.String") && value == null))
                       {
                        throw new NullPointerException(field.getName() + "的值为空");
                    }else if( typeName.equals("int") ){
                        Integer v = (Integer) value;
                        if(v == 0)
                            throw new NullPointerException(field.getName() +"的值为0");
                    }
                }

            }
        }



}
/**
*
*在字段中使用自定义注解:MyAnno
*/
public class AnnoTest {
   @MyAnno(NOTNULL = true)
   public String name;
    @MyAnno
   public String id;
    @MyAnno(NOTNULL = true)
    public int number;

    public AnnoTest(){}
    public AnnoTest(String name) {
        this.name = name;
    }

    public AnnoTest(String name, int number) {
        this.name = name;
        this.number = number;
    }

    
  }


测试1

    public static void main(String[] args) throws IllegalAccessException {
        ParseMyAnno parseMyAnno = new ParseMyAnno();
        AnnoTest t = new AnnoTest();//name =null,number=0
        parseMyAnno.parse(AnnoTest.class,t);
    }

Exception in thread "main" java.lang.NullPointerException: name的值为空
	at filter.at.ParseMyAnno.parse(ParseMyAnno.java:30)
	at filter.at.ParseMyAnno.main(ParseMyAnno.java:46)

测试2

    public static void main(String[] args) throws IllegalAccessException {
        ParseMyAnno parseMyAnno = new ParseMyAnno();

        AnnoTest t = new AnnoTest("name11");//number=0
        parseMyAnno.parse(AnnoTest.class,t);
    }

Exception in thread "main" java.lang.NullPointerException: number的值为0
	at filter.at.ParseMyAnno.parse(ParseMyAnno.java:34)
	at filter.at.ParseMyAnno.main(ParseMyAnno.java:49)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值