0
点赞
收藏
分享

微信扫一扫

Java中如何自定义注解

Android开发指南 2022-03-12 阅读 77

定义:
注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

作用:
1、编写文档:通过代码里标识的注解生成文档【生成文档doc文档】
2、代码分析:通过代码里标识的注解对代码进行分析【使用反射】
3、编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【Override】

注解和注释的区别:

JDK中预定义的一些注解:

  • @Override :检测被该注解标注的方法是否是继承自父类(接口)的
  • @Deprecated:该注解标注的内容,表示已过时
  • @SuppressWarnings:压制警告
    • 一般传递参数all @SuppressWarnings(“all”)

自定义注解:

**格式:**
//元注解列表
public @interface 注解名称{
		//属性列表
		public 属性类型 属性名() default 默认值 ; //public可以省略
	}	

注解的本质就是一个接口,该接口默认继承Annotation 接口,

public interface MyAnno extends java.lang.annotation.Annotation {}

注解的属性列表:可以等同理解为接口中的抽象方法。

1、属性返回值类型的取值

2、定义了属性,在使用时需要给属性赋值

3、元注解:就是用来描述注解的注解

//自定义注解代码案例
@Retention(RetentionPolicy.RUNTIME)	
@Target(value = ElementType.TYPE)
public @interface Anno1 {
	//定义一个基本类型的属性
	int a () default 23;
	//定义一个String类型的属性
	public String name() default "itheima";
	//定义一个Class类型的属性
	public Class clazz() default Anno2.class;
	//定义一个注解类型的属性
	public Anno2 anno() default @Anno2;
	//定义一个枚举类型的属性
	public Season season() default Season.SPRING;
	//以上类型的一维数组
	//int数组
	public int[] arr() default {1,2,3,4,5};
	//枚举数组
	public Season[] seasons() default {Season.SPRING,Season.SUMMER};
	//value。后期我们在使用注解的时候,如果我们只需要给注解的value属性赋值。那么value就可以省略
	public String value();
	
}
	
//在使用注解的时候如果注解里面的属性没有指定默认值。那么我们就需要手动给出注解属性的设置值。
//@Anno1(name = "study")
@Anno1("abc")	 //该注解作用在类上
public class AnnoDemo {
	//...
}

4、程序使用注解的过程

  • 获取注解定义的位置的对象 (Class,Method,Field)
  • 获取指定的注解 getAnnotation(Class),其实就是在内存中生成了一个该注解接口的子类实现对象
  • 调用注解中的抽象方法获取配置的属性值

案例:
自定义注解,使用注解,并通过Java反射机制获取注解中的参数值

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

/**
 * 自定义注解
 */
@Retention(RetentionPolicy.RUNTIME)	//保留时间或生命周期
@Target(value = ElementType.METHOD)	//作用在方法上
public @interface Execute {

    String value() default "this is an annotation.";

    String[] paramData() default {"1","2"};

}

import lombok.Data;

/**
 * 使用注解
 */
@Data
public class AnnotationDemo {


    public void demo1(){
        System.out.println("demo1 : 没有加注解 执行了。。。");
    }


    @Execute(value = "我是注解的默认值")
    public void demo2(){
        System.out.println("demo2 加了注解 执行了。。。");
    }


    public void demo3(){
        System.out.println("demo3 没有注解 执行了。。。");
    }


}
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 通过反射获取注解并获取其中的属性值
 */
public class AnnoTest {

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
        //通过反射获取UseTest类的字节码文件对象
        Class<?> aClass = Class.forName("com.awe.hrm.anno.AnnotationDemo");
        //通过Class对象创建当前类对象
        AnnotationDemo o = (AnnotationDemo) aClass.newInstance();
        //获取这个类里面所有的方法对象
        Method[] declaredMethods = aClass.getDeclaredMethods();
        //遍历方法对象数组
        for (Method declaredMethod : declaredMethods) {
            //判断当前方法对象中是否包含(Execute)注解
            if (declaredMethod.isAnnotationPresent(Execute.class)) {
                //执行当前有注解方法
                declaredMethod.invoke(o);
                //获取当前方法上注解的 (value)属性的值并打印
                String value = declaredMethod.getAnnotation(Execute.class).value();
                System.out.println(value);
                //获取当前方法上注解的 (paramData)属性的值并遍历打印
                String[] strings = declaredMethod.getAnnotation(Execute.class).paramData();
                for (String string : strings) {
                    System.out.println(string + ",");
                }
            }
        }
    }
}

main方法执行打印结果:

小结:

  • 注解不是程序的一部分,可以理解为注解就是一个标签
举报

相关推荐

0 条评论