前言
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。
- 反射的作用?
- 三种获取Class对象的方式
- 获取构造器实例化对象和属性信息
- 获取包信息
- 获取方法
- 小结
1 反射的作用
- 在运行时判定任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判定任意一个类所具有的成员变量和方法;
- 在运行时调用任意一个对象的方法;
2 三种获取Class对象的方式
第一种:Object类中的getClass()方法 第二种:类.class 第三种:通过Class类的forName()方法
// 第一种
Class<?> class1 = new Kitty().getClass();
// 第二种
Class<?> class2 = Kitty.class;
// 第三种
Class<?> class3 = Class.forName("com.ayu.demo.reflection.Kitty");
都拿到了同一个结果。
3 获取构造器实例化对象和属性信息
废话不多说,上个简单的例子。
// 猫咪类
public class Kitty {
private String name;
private String color;
public Kitty() {
}
public Kitty(String name, String color) {
this.name = name;
this.color = color;
}
public void action() {
System.out.println(color + name + "在卖萌");
}
}
// 测试类
public class ReflectionTest {
public static void main(String[] args) {
try {
// 第一种
Class<?> class1 = new Kitty().getClass();
// 获取所有的构造器
Constructor<?>[] constructors = class1.getConstructors();
// 获取某个构造器
Constructor<?> constructor = class1.getConstructor(String.class, String.class);
// 得到实例化对象
Kitty kitty = (Kitty) constructor.newInstance("小猫咪", "白色的");
kitty.action();
// 获取color属性
Field color = class1.getDeclaredField("color");
// 跳过安全检测
color.setAccessible(true);
System.out.println("kitty对象color属性的值:" + color.get(kitty));
// kitty对象中的color属性值改为【黑色的】
color.set(kitty, "黑色的");
kitty.action();
} catch (Exception e) {
e.printStackTrace();
}
}
}
代码还是比较简单的。 通过反射得到构造器,然后实例化出猫咪对象。 得到color属性,由于它是private,所以需要
setAccessible(true)跳过安全检查,然后就可以拿到属性信息,或者更改。
4 获取包信息
Class<?> class1 = Kitty.class;
Package aPackage = class1.getPackage();
aPackage.getName(); // 包名
5 获取方法
Class<?> class1 = Kitty.class;
// 获取构造器
Constructor<?> constructor = class1.getConstructor(String.class, String.class);
// 得到实例化对象
Kitty kitty = (Kitty) constructor.newInstance("小猫咪", "白色的");
// 获取action方法
Method method = class1.getMethod("action");
method.invoke(kitty); // 调用action方法
如果action方法需要传入参数,则需要
getMethod中声明,比如
// action方法需要传入String类型参数
public void action(String action) {
System.out.println(color + name + action);
}
// 加上String.class
Method method = class1.getMethod("action", String.class);
method.invoke(kitty, "在打滚儿");
6 小结
反射可以赋予JVM动态编译的能力,提升服务器性能,可以使得我们的程序更加灵活,避免写死,特别是在架构的设计中,反射是非常有用的。
另外,反射是一种在运行时获取和使用元数据的技术,其本质在于元数据。有时间博主会继续更新相应文章。