1.概念
注解表示一个标识(标注、标记),它可以用在类上、方法上、变量上等,给类的各个组成部分一些额外的表示,能够被编译器识别。
2.常见注解
@Override: 描述一个方法是复写的父类方法
@Deprecate: 描述一个方法是过时的方法,调用过时的方法会有一个横线
@SuppressWarnings(value = “all”): 压制警告:写在类上,则压制整个类的警告,在方法上则压制方法上的警告
3.自定义注解
【在使用注解的时候如果注解里面的属性没有指定默认值,那么我们就需要手动给出注解属性的设置值。】
public @interface Anno {//定义一个基本类型的属性//public属性类型属性名() default 默认值;int a() default 23 "张三";//定义一个String类型的属性public String name() default 23;//定义一个class类型的属性public Class clazz() default Anno2.class;//定义一个注解类型的属性public Anno2 anno() default @Anno2;//定义一个枚举类型的属性public Week week() default Week.Monday;//以上类型的一维数组//int 数组public int [] arr() default {1,2,3,4,5}//枚举数组public Week[] weeks() default{Week.Monday}public String value();//特殊属性value 变量只有一个,则使用时可以省略名称直接赋值
}//类上使用注解
//在使用注解的时候如果注解里面的属性没有指定默认值,那么我们就需要手动给出注解属性的设置值。
//此处相当于Anno的对象,只是给类或者方法添加了一个标签,不会影响实体
@Anno("李四")
public class Demo1 {public static void main(String[] args) {}
}
4.元注解
@Target:指定了注解能在哪里使用【成员变量、类、方法】
@Retention:可以理解为保留时间(生命周期)
@lnherited:表示修饰的自定义注解可以被子类继承
@Documented:表示该自定义注解,会出现在API文档里面
//定义特殊属性value
@Retention(RetentionPolicy.RUNTIME) //注解在运行时期有效
@Target(ElementType.TYPE)//注解可以使用在类上
//@Target(ElementType.METHOD)//注解可以使用在方法上
//@Target(ElementType.FIELD)//注解可以使用在成员变量上
@Inherited//表示修饰的自定义注解可以被子类继承
public @interface Anno {
}//测试类
public class Demo2 {public static void main(String[] args) throws ClassNotFoundException {//得到类的字节码对象Class<?> personClazz = Class.forName("com.itheima3.Person");//getAnnotation(Anno.class);得到该类的注解对象Anno a1 = personClazz.getAnnotation(Anno.class);Class<?> studentClazz = Class.forName("com.itheima3.Student");Anno a2 = personClazz.getAnnotation(Anno.class);System.out.println(a1==a2);}
}打印结果
true
5.自定义注解实现
测试让有注解的方法执行,没有Test的方法不执行
//自定义注解
//元注解[对注解进一步进行说明]
@Target(ElementType.METHOD)//指定注解可以用在哪些地方
@Retention(RetentionPolicy.RUNTIME)//表示注解的存活时间可以到运行
//定义一个注解
public @interface Test {
}//方法类
public class UseTest {//没有使用Test注解public void show(){System.out.println("UseTest....show....");}//使用Test注解@Testpublic void method(){System.out.println("UseTest....method....");}//使用Test注解@Testpublic void function(){System.out.println("UseTest....function....");}
}//测试类
//测试让有注解的方法执行,没有Test的方法不执行
public class AnnoDemo {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//通过反射获取UseTest的字节码文件对象Class<?> clazz = Class.forName("com.itheima2.UseTest");//2.通过反射获取这个类里面所有方法的对象Method[] methods = clazz.getDeclaredMethods();//创建对象用于执行方法Object o = clazz.getConstructor().newInstance();//遍历数组,得到每一个方法对象for (Method method : methods) {//getAnnotation(Test.class)返回原方法上额外的注解Test test = method.getAnnotation(Test.class);//如果有注解,就执行if (test != null) {//注解没有设置存活时间,则打印无结果method.invoke(o);}//method.isAnnotationPresent(Test.class)判断方法上是否有注解,有则返回true/*if(method.isAnnotationPresent(Test.class)){method.invoke(o);}*/}}
}打印结果:
-------------------------------------------------------------------------------
UseTest....method....
UseTest....function....