Java反射的一些知识
1 反射的用途
反射的功能:
- JVM运行时,动态获取一个类,并可执行其方法
反射的常见用途:
- IDE输入类名.,代码补全
- 开发框架,根据不同配置文件加载不同的类,运行时动态加载需要的对象
反射的宏观用途:
- 补充Java动态性的不足(Java是静态语言,但有其动态一面)
注:Java中弥补动态性的机制:
- 反射
- 泛型
- 动态脚本
2 反射的实例
假设有一个Apple类定义如下:
import java.lang.reflect.Constructor;
class Apple {
private Integer price;
public Integer getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int add(int a, int b) {
return a + b;
}
public Apple() {
}
public Apple(Integer price) {
}
}
Apple类中,除了价格price外,有一个add(int, int)方法…
2.1 通过反射创建一个Apple类的对象
通过通过反射创建一个类的对象的方法有:
- 通过class.newInstance()
- 通过constructor.newInstance()
如果通过第一种方式创建,获取class对象的方式有:
- Class.forName(className)
- Class.class
- object.getClass()
以下代码:
- 通过Class.class获取Apple的class对象
- 通过class.newInstance()创建对象
public static void main(String[] args) throws Exception {
Class<?> c = Apple.class;
Apple apple = (Apple) c.newInstance(); //newInstance只能调用无参构造函数
System.out.println(apple.price);
}
2.2 通过反射调用一个类中的方法
通过反射调用一个类中的方法(已经知道这个方法的名字):
- 获取Apple的class对象c
- 通过c获取其中的方法
- 调用方法
public static void main(String[] args) throws Exception {
Class<?> c = Apple.class;
Method method = c.getDeclaredMethod("add", int.class, int.class);
System.out.println(method.invoke(c.newInstance(), 1, 2));
//其中,第一个参数用于指定调用该方法的对象
}
注:
- getDeclaredMethod()可以获取本类定义的方法,包括私有方法
- getMethods()可以获取所有公有的方法,包括继承的方法,不包括私有方法
3 反射的一些知识点
3.1 使用反射的一个例子
根据人(age, gende)、票价(price)计算不同的人的票价:
- 设计一个规则类,类中有方法如price100ForAge10Male()
- 根据人和票价动态生成方法名如pricexxxForAgexxMale
- 通过反射,根据动态生成的方法名去调用规则类的具体的方法