Java的注解、反射等机制的产生,让动态代理成为可能,一般通过全限定名+类名,找到类,可以invoke它的构造方法以及其他方法,可以获取它的参数(Field)名称和值。
注解一般用在代码的注释上、代码审查上(有没有按标准写,比如inspect)、代码注入(hook,asbectj),需要考虑的是,在何时注入(编译期还运行期)
反射一般用在动态将json和Object互相转化,执行相关底层代码;
Java中基本的Annotation如下:
@Override:用来指定方法覆载,他可以指定一个子类必须覆盖父类的某一个方法。它会告诉编辑器检查这个方法,保证父类有一个被该方法重写的方法,否则就会报错,也帮助程序员避免一些低级错误。
@Deprecated:表示程序中某个元素(类或者方法)已过时,当其他程序使用已过时的类或方法时会发出警告。
@SuppressWarnings:指示被Annotation修饰的程序元素(以及该程序元素中所有的子类)取消显示的编译器警告;
@SafeVarargs:避免堆污染警告的发出;
1)、可以使用@SafeVarargs修饰引发堆污染警告的方法或者构造器;
2)、使用@SuppressWarnings(“unchecked”)来修饰;
3)、编译时使用-Xlint:varargs选项;
第三种不太懂,下去整明白啦再来添加。
什么时候会发生堆污染?讲一个不带泛型的对象赋给一个带泛型的变量时,便会发生时堆污染,对于形参的个数可变的方法,该形参的类型又是泛型时更容易导致堆污染。
@FunctionalInterface:用来指定某个接口必须是函数式接口,但是值得注意的是@FunctionalInterface只能修饰接口,不能修饰其他程序元素。他也能帮助程序员避免一些低级的错误。
什么是函数式接口呢?
java8中规定如果接口中只有一个抽象方法(可以包含多个默认的方法或者static修饰的静态方法)该接口便是函数式接口。
@Retention 只能修饰Annotation定义,用来指定被修饰的Annotation可以保留多久,它包含RetentionPolicy类型的value成员变量,故使用@Retention事必须为其value变量赋值,value成员变量只能是如下三个:
RetentionPolicy.CLASS:编译器将注释记录在class文件中。当java程序运行时,JVM不能获取到相关的Annotation信息,此为默认值;
RetentionPolicy.RUNTIME:编译器将注释记录在class文件中,当Java程序运行时,Jvm可以获取到Annotation的信息,程序可以通过反射获取到相关的Annotation信息。
RetentionPolicy.SOURCE:Annotation只保留在源代码中,编译器直接丢弃这种Annotation。
@Target只能修饰一个Annotation定义,用来被指定Annotation能用于修饰那些程序单元。它也包含一个名为value的成员变量;该变量的值仅能是如下几个:
ElementType.ANNOTATION_Type:指定该策略的Annotation只能修饰Annotation;
ElementType.CONSTRUCTOR:指定该策略的Annotation只能修饰构造器;
ElementType.FIELD:指定该策略的Annotation只能修饰成员变量;
ElementType.LOCAL_VARIABLE:指定该策略的Annotation只能修饰局部变量;
ElementType.METHOD:指定该策略的Annotation只能修饰方法定义;
ElementType.PACKAGE:指定该策略的Annotation只能修饰包定义;
ElementType.PARAMETER:指定该策略的Annotation只能修饰参数;
ElementType.TYPE:指定该策略的Annotation只能修饰类、接口(宝或注解类型)或枚举定义;
使用@Target可以直接在括号中定义,无需使用name=value的形式。
@Documented 用于指定被该原Annotation修饰的Annotation类将被javac工具提取成文档
@Inherited:指定被他修饰的Annotation具有继承性
@Interface: 在interface之前加一个@符号来表示它是一个注解。一旦你定义了一个注解之后,你可以在代码中用它,和之前的例子一样。
以上是对注解简单的总结,有那里不对的地方还请多指正。