java反射机制的定义:java
在运行转态时(动态的)时。web
对于任意一个类,都可以知道这个类的全部属性和方法spring
对于任意一个对象,都可以知道调用它的任意属性和方法api
java中用对象来对现实生活中的事物进行抽象,如人(现实生活)抽象到一个person类(java对象)。但有没有想过,java中的类(现实生活)其实也是一个Class对象(对象)。所以,这个Class类就包含了全部你定义的Class信息,包括全部的方法(私有,公有)、构造器、实现了那些方法、哪些注解信息、全部的属性等相关的信息,它还提供newInstance()方法来生成实例。安全
Class对象是一个至关特殊的对象,是一个超泛化的对象,是全部对象的对象。所以智能由JVM在建立其余对象的时候自动建立,所以Class对象又称包含了其余对象的字节码的信息的对象。app
Class类是反射机制的起源,咱们获得Class类对象有3种方法:框架
第一种:经过类名得到ide
Class<?> class = ClassName.class;工具
第二种:经过类名全路径得到:ui
Class<?> class = Class.forName("类名全路径");
第三种:经过实例对象得到:
Class<?> class = object.getClass();
总结:第一种方法:类字面常量使得建立Class对象的引用时不会自动地初始化该对象,而是按照以前提到的加载,连接,初始化三个步骤,这三个步骤是个懒加载的过程,不使用的时候就不加载。
第二种方法:Class类自带的方法。
第三种方法:是全部的对象都可以使用的方法,由于getClass()方法是Object类的方法,全部的类都继承了Object,所以全部类的对象也都具备getClass()方法。
建议:使用类名.class,这样作即简单又安全,由于在编译时就会受到检查,所以不须要置于try语句块中,而且它根除了对forName()方法的调用,因此也更高效。
看完反射的定义,咱们就知道,反射机制就是增长了程序的灵活性,最重要的用途就是来开发通用型的框架,如Spring,将全部类的bean交给spring容器管理。不管是XML配置仍是注解配置,当咱们获取bean时,容器都会读取配置,这些配置就是类的信息,容器根据反射,生成实例返回。具体的做用还有动态代理、切面逻辑等等,其本质就是反射。
注解(Annotation)就是Java提供了一种元程序中的元素关联任何信息或者任何元数据(metadata)的途径和方法,Annotation(注解)是一个接口,程序能够经过放射来获取指定的程序元素的Annotation对象,而后经过Annotation对象来获取注解里面的元数据。
Annotation能被用来为某个程序元素(类、方法、成员变量等)关联任何的信息。须要注意的是,这里存在着一个基本的规则:Annotation不能影响程序代码的执行,不管增长、删除Annotation,代码都始终如一的执行;另外,尽管一些annotation经过java的放射api方法在运行时被访问,而java语言解释器在工做时忽略了这些annotation。正是因为java虚拟机忽略了annotation,致使了annotation类型在代码中“不起做用”的;只有经过某种配套的工具才会对annotation类型中的信息进行访问和处理。
元数据从metadata一词译来,就是“关于数据的数据”的意思。
元数据的功能做用有不少,好比:你可能用过Javadoc的注释自动生成文档。这就是元数据功能的一种。总的来讲,元数据能够用来建立文档,跟踪代码的依赖性,执行编译时格式检查,代替已有的配置文件。若是要对于元数据的做用进行分类,目前尚未明确的定义,不过咱们能够根据它所起的做用,大体可分为三类:
1. 编写文档:经过代码里标识的元数据生成文档
2. 代码分析:经过代码里标识的元数据对代码进行分析
3. 编译检查:经过代码里标识的元数据让编译器能实现基本的编译检查
在Java中元数据以标签的形式存在于Java代码中,元数据标签的存在并不影响程序代码的编译和执行,它只是被用来生成其它的文件或针在运行时知道被运行代码的描述信息。
综上所述:
第一,元数据以标签的形式存在于Java代码中。
第二,元数据描述的信息是类型安全的,即元数据内部的字段都是有明确类型的。
第三,元数据须要编译器以外的工具额外的处理用来生成其它的程序部件。
第四,元数据能够只存在于Java源代码级别,也能够存在于编译以后的Class文件内部。
Annotation:
Annotation使用了在java5.0所带来的新语法,它的行为十分相似public、final这样的修饰符。每一个Annotation具备一个名字和成员个数>=0。每一个Annotation的成员具备被称为name=value对的名字和值(就像javabean同样),name=value装载了Annotation的信息。
Annotation类型:
Annotation类型定义了Annotation的名字、类型、成员默认值。一个Annotation类型能够说是一个特殊的java接口,它的成员变量是受限制的,而声明Annotation类型时须要使用新语法。当咱们经过java反射api访问Annotation时,返回值将是一个实现了该 annotation类型接口的对象,经过访问这个对象咱们能方便的访问到其Annotation成员。
根据注解参数的个数,咱们能够将注解分为三类:
1.标记注解:一个没有成员定义的Annotation类型被称为标记注解。这种Annotation类型仅使用自身的存在与否来为咱们提供信息。好比后面的系统注解@Override;
2.单值注解
3.完整注解
根据注解使用方法和用途,咱们能够将Annotation分为三类:
1.JDK内置系统注解
2.元注解
3.自定义注解
注解的语法比较简单,除了@符号的使用外,他基本与Java固有的语法一致,JavaSE中内置三个标准注解,定义在java.lang中:
@Override:用于修饰此方法覆盖了父类的方法;
@Deprecated:用于修饰已通过时的方法;
@SuppressWarnnings:用于通知java编译器禁止特定的编译警告。
元注解的做用就是负责注解其余注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型做说明。Java5.0定义的元注解:
1.@Target,
2.@Retention,
3.@Documented,
4.@Inherited
@Target说明了Annotation所修饰的对象范围。取值(ElementType)有
1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Retention定义了该Annotation被保留的时间长短,如某些Annotation仅出如今源码中,而被编译器丢弃。取值(RetentionPoicy)有:
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)
属性值是RUTIME,这样注解处理器能够经过反射,获取到该注解的属性值,从而去作一些运行时的逻辑处理属性值是RUTIME,这样注解处理器能够经过反射,获取到该注解的属性值,从而去作一些运行时的逻辑处理
@Documented用于描述其余类型的annotation应该被做为被标注的程序成员公共的API,所以能够被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Column { public String name() default "fieldName"; public String setFuncName() default "setField"; public String getFuncName() default "getField"; public boolean defaultDBValue() default false; }
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。若是一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
package annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FruitName { String value() default ""; }
Java spring开发时,常常在一个类上有多个注解,如SpringMVC注解
@RestController
@RequestMapping(‘/person’)
能够合并成一个
@PathRestController(‘/person’)
实现是
import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.core.annotation.AliasFor; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @RestController @RequestMapping public @interface PathRestController { @AliasFor("path") String[] value() default {}; @AliasFor("value") String[] path() default {}; }