Java的反射&内省
一、Java基础之反射
1、概述
在运行状态中,对于任意一个类都能够知道改类的所有属性和方法;对于任何一个对象都能够调用该对象的任意方法和属性。这种动态获取类的信息以及动态调用对象的属性和方法的机制称为Java的反射机制。
要解剖一个类,必须先获取到改类的字节码文件对象,而解剖就要使用Class类中的方法。字节码对象就是Class类型的对象。
Class对象是由Java虚拟机自动创建。
2、获取Class对象
获取Class对象的三种方法:
- object ——> getClass()
- 任何类型都有静态属性class,包括基本数据类型
- Class类的静态方法:Class.forName(“类的全路径”)
3、Class对象的使用
getDeclared* 表示获取所有的,不受限定符的影响
主要是通过Class对象获取到Field
,Method
和Constructor
对象。
使用到的主要方法:
方法 | 注解 |
---|---|
static Class<?> forName(String className) | 返回给定className的类或接口的Class对象 |
Constructor<?>[] getConstructors() | 返回包含Constructor 对象一个数组,表示的该类的所有public构造函数 类 对象。 |
Constructor getConstructor(Class<?>… parameterTypes) | 返回一个指定参数类型的public构成函数的 Constructor 对象 |
Constructor getDeclaredConstructor(Class<?>… parameterTypes) | 返回一个 Constructor 对象,该对象反映 Constructor 对象表示的类或接口的指定 类 函数。 |
Field getDeclaredField(String name) | 返回一个 Field 对象,它反映此表示的类或接口的指定已声明字段 类 对象。 |
Method getDeclaredMethod(String name, Class<?>… parameterTypes) | 返回一个 方法 对象,它反映此表示的类或接口的指定声明的方法 类 对象。 |
二、内省
1、内省是什么
Java语言对Bean类属性、事件的一种缺省处理方法。例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值。通过getName/setName来访问name属性,这就是默认的规则。
Java中提供了一套API用来访问某个属性的getter/setter方法,通过这些API可以使你不需要了解这个规则(但你最好还是要搞清楚),这些API存放于包java.beans中。
实现方式:
- 内省(Introspector)是Java语言对Bean类属性、事件的一种缺省处理方法。
- 例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值。
- 通过getName/setName来访问name属性,这就是默认的规则。
- Java中提供了一套API用来访问某个属性的getter/setter方法,通过这些API可以使你不需要了解这个规则,
- 这些API存放于包java.beans中。
一般的做法是通过类Introspector来获取某个对象的BeanInfo信息, 然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法。
2、内省和反射区别
区别:
反射是在运行状态把Java类中的各种成分映射成相应的Java类,可以动态的获取所有的属性以及动态调用任意一个方法,强调的是运行状态。
内省机制是通过反射来实现的,BeanInfo用来暴露一个bean的属性、方法和事件,以后我们就可以操纵该JavaBean的属性。
主要使用到的类:
BeanInfo
, Introspector
,PropertyDescriptor
和MethodDescriptor
-
使用
BeanInfo
界面创建一个BeanInfo
类,并提供关于bean的方法,属性,事件和其他功能的显式信息。 -
Introspector
类提供了一种标准的工具来了解目标Java Bean支持的属性,事件和方法。对于这三种信息中的每一种,Introspector
将分别分析bean的类和超类,寻找显式或隐式信息,并使用该信息构建一个全面描述目标bean的BeanInfo对象。 -
PropertyDescriptor
描述了Java Bean通过一对访问器方法导出的一个属性。 -
MethodDescriptor
描述了Java Bean支持的特定方法,用于从其他组件进行外部访问。