Java的反射机制
一、反射的定义
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
二、反射的使用
1.反射是通过什么实现的?
反射是通过Class类的对象实现的。Class对象存储在堆中(jdk1.7)之前,我们获取一个类的对象时,是通过类的构造器去创建该类的对象。有的时候,当一个类的构造器声明为private时,我们就不能从该类的外部去调用该类的构造器去创建对象,这个时候我们就可以使用反射机制来获取该类中所有的属性和方法。
2.实现反射的步骤
① 获取当前类的Class对象。(共有三种方式)
1). 通过 “类名.class”的方式
2). 通过Class类中的forName(String name),参数表示类的全路径名。
3). 通过该类 实例对象的getClass();
② 设置构造器的访问权限,获取当前类的构造函数
使用setAccessible()设置构造器的访问权限。
1).使用Class对象的getConstructor(Class …ParameterTypes), 该方法用来获取类中只声明为public的构造器。参数Class…Parameter Types表示该参数类型的Class对象。
2).使用getDeclaredConstructor(Class…ParameterTypes) 该方法用来获取类中所有权限修饰符的构造器,(一次只能获取一个)。
3).使用 getDeclaredConstructors()获取该类中所有的构造器,并将它们存储到一个数组中。
3.通过反射获取类中的方法
① 通过获取的构造器,使用newInstance()获取该类的对象
② 获取类中的方法,使用通过newInstance()获取的对象,让其调用getDeclaredMethod(String name),以及使用setAccessible()设置方法的访问权限。
③ 使用invoke(Object obj) 实现方法的调用
代码如下(示例):
public class TestDemo1 {
// 将构造器设为私有的,就不能去new 对象了。这个时候,我们使用该类的对象,就要去使用反射机制。
private TestDemo1(){
}
public void eat(){
System.out.println("中午了,该吃饭了");
}
public static void main(String[] args){
//1. 先获取当前类的Class对象。 通过 ① 类名.class;
Class<TestDemo1> testDemo1Class = TestDemo1.class;
//2. 通过当前类的Class对象 获取当前类的构造器
try {
// 获取当前类的 无参构造器
Constructor<TestDemo1> declaredConstructor = testDemo1Class.getDeclaredConstructor();
//3. 获取类的构造器,我们将类的构造器 设置会 可访问的。
declaredConstructor.setAccessible(true);
//4. 通过类的构造器,获取类的对象
TestDemo1 testDemo1 = declaredConstructor.newInstance();
//5. 获取该类中的方法
Method eat = testDemo1Class.getDeclaredMethod("eat");
//6. 将该方法设置会可访问的。(防止是声明为private的方法。)
eat.setAccessible(true);
//6. 调用eat方法,通过invoke(Object obj): 表示,调用当前对象的 eat方法。
eat.invoke(testDemo1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.通过反射获取类中的属性
1. 在获取对象后,我们再通过该类的class对象去获取类中的属性
使用 getDeclaredFiled();
getFiled();
getDeclaredFileds();
getFileds();
使用方法 同理 构造器。
2. 获取类的属性后,我们将该属性 通过setAccessible(true) 设置为 可访问的。
3. 再使用 我们通过反射获取的 属性 的 set(Object o, String name); 去设置属性值
参数一: Object o : 指明修改 哪个类的该属性的值。
参数二: 要修改的属性值。
4. 最后通过 反射获取的 属性 的 get(Object o) 去获取属性的值。
代码如下(示例):
public class TestDemo2 {
public static void main(String[] args) {
//1.获取People类的Class对象
Class<People> peopleClass = People.class;
//2.获取People类的有参构造
try {
Constructor<People> string_name = peopleClass.getDeclaredConstructor(String.class);
//3. 将构造器的权限 设置为可访问的。
string_name.setAccessible(true);
//4. 获取该类的对象
Object o = string_name.newInstance("lisi");
//5. 获取name属性
Field name = peopleClass.getDeclaredField("name");
//6. 将name属性 设置会 可访问的。
name.setAccessible(true);
//7. 修改name的值
name.set(o,"zs");
//8. 获取name的值
System.out.println(name.get(o));
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 通过反射,将name修改为"zs", 调用有参构造生成对象。
class People{
private String name;
private People(){
}
private People(String name){
this.name = name;
}
}
在运行阶段,JVM会创建一个该类的Class对象。这个Class对象只存在一份。且该对象中包含这个类的所有信息。反射的本质是,拿到Class对象后,反向获取类的信息。
1193

被折叠的 条评论
为什么被折叠?



