注解
注解
注解其实就是代码中的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相对应的处理
传统的方式,我们是通过配置文件(xml文件)来告诉类是如何运行的。
有了注解技术以后,我们就可以通过注解告诉类如何运行
在JDK中注解分为了
-
基本Annotation:在lang包下,用于常用于标记该方法,抑制编译器警告等
-
元Annotaion:在annotaion包下,常用于修饰其他的Annotation定义
基本注解
-
@Override 重写
-
,该注解也非常常见,Java在设计的时候,可能觉得某些方法设计得不好,为了兼容以前的程序,是不能直接把它抛弃的,于是就设置它为过时。
-
@SuppressWarnings 抑制编译器警告,可以用它来让编译器不给予我们警告,当我们在使用集合的时候,如果没有指定泛型,那么会提示安全检查的警告
-
@SafeVarargs "堆污染"警告,当把一个不是泛型的集合赋值给一个带泛型的集合的时候,这种情况就很容易发生堆污染….
-
@FunctionalInterface 指定该接口是函数式接口,用该注解显示指定该接口是一个函数式接口
自定义注解基础
标记Annotation
没有任何成员变量的注解称作为标记注解,@Overried就是一个标记注解
//有点像定义一个接口一样,只不过它多了一个@ public @interface MyAnnotation { }
元数据Annotation
public @interface MyAnno { //定义成员变量 String getString(); int getInt(); //定义成员变量并设置默认值 String name() default "tom"; }
-
-
在注解上定义的成员变量只能是 8中基本类型(byte,boolean,char,short,int,long,float,double,)和 String,Enum,Class,annotation类型,以及这些类型的数组
-
还有一种特殊的情况,如果注解上只有一个属性,并且属性的名称为value,那么在使用的时候,我们
把注解上的信息注入到方法上利用的是反射技术
步骤可分为三部:
-
反射出该类的方法
-
通过方法得到注解上具体的信息
-
将注解上的信息注入到方法上
// 注解 @Retention(RetentionPolicy.RUNTIME) public @interface MyAnno { String name(); int age(); } //使用注解 public class TestAnno { @MyAnno(name = "tom",age = 18) public void test1(String name,int age){ System.out.println(name+","+age); } public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { Class test=TestAnno.class; Method method=test.getMethod("test1",String.class,int.class); MyAnno anno=method.getAnnotation(MyAnno.class); String name=anno.name(); int age=anno.age(); TestAnno testAnno= (TestAnno) test.newInstance(); method.invoke(testAnno,name,age); } }
元注解
元Annotation都是用于修饰其他的Annotation定义
@Retention
@Retention只能用于修饰其他的Annotation,用于指定被修饰的Annotation被保留多长时间。
@Retention 包含了一个RetentionPolicy类型的value变量,所以在使用它的时候,必须要为value成员变量赋值,RetentionPolicy有三个值:SOURCE,CLASS,RUNTIME,对应java文件的三个时期:编译,class,运行。@Retention默认是class
因为@Retention默认是class,而反射是在运行时期来获取信息的。因此前面使用自定义注解时就要设置为RetentionPolicy.RUNTIME
@Target
@Target也是只能用于修饰另外的Annotation,它用于指定被修饰的Annotation用于修饰哪些程序单元
@Target是只有一个value成员变量的,该成员变量的值是以下的:TYPE(给一个类型进行注解,比如类、接口、枚举),FIELD,METHOD,PARAMETER(方法内的参数),CONSTRUCTOR,LOCAL_VARIABLE(局部变量),ANNOTATION_TYPE,PACKAGE
@Documented
@Documented用于指定被该Annotation修饰的Annotation类将被javadoc工具提取成文档
@Inherited
@Inherited也是用来修饰其他的Annotation的,被修饰过的Annotation将具有继承性。。。
例子:
-
@xxx是我自定义的注解,我现在使用@xxx注解在Base类上使用….
-
使用@Inherited修饰@xxx注解
-
当有类继承了Base类的时候,该实现类自动拥有@xxx注解
把对象注入到方法、属性中
把对象注入到方法中:
-
得到想要类中注入的属性
-
得到该属性的对象
-
得到属性对应的写方法
-
通过写方法得到注解
-
获取注解详细的信息
-
将注解的信息注入到对象上
-
调用属性写方法,将已填充数据的对象注入到方法中
把对象注入到属性中:
-
得到想要注入的对象属性
-
通过属性得到注解的信息
-
通过属性的写方法将注解的信息注入到对象上
-
最后将对象赋给类