反射机制可以完成:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时得到任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的成员变量和方法
- 生成动态代理
反射最重要的用途就是开发各种通用框架,为了保证框架的通用性,它们可能需要根据配置文件加载不同的对象或类,调用不同的方法,这个时候就必须用到反射——运行时动态加载需要加载的对象。
按我的理解就是,平常情况下我们知道自己要用什么类,知道要用什么类的什么方法,调用方法
Student s = new Student();
s.showSAge();
就如上所示,但根据配置文件加载不同的对象或类时,我们在编程中并不知道自己要用什么类的什么方法,类和方法像变量一样不可确定,但又要调用配置文件中的方法,就要用到反射。
具体操作如下:
public class People {
public String name = "people";
public int age = 1;
public void showName() {
System.out.println("People name is " + name);
}
public void showPAge() {
System.out.println("People age is " + age);
}
public static void main(String[] args) throws Exception {
String className = "testt.People";
String methodName = "showName";
Class cla = Class.forName(className);
Object obj = cla.newInstance();
System.out.println(obj.getClass());
Method met = cla.getMethod(methodName);
met.invoke(obj);
}
}
运行结果如下:
一般情况下类名和方法名通过配置文件读出来,我这里直接给了值,方便观察。与一开始不同的是,类和方法变成了变量般的存在,我们可以随意修改className和methodName,只要是合法的,便可以在不修改代码的情况下调用任意类的方法。
另外反射相关类还有Field类和Constructor类,和Method类都在java.lang.reflect下
通过Constructor类使用指定的初始化参数创建和初始化构造函数声明类的新实例实例如下:
public class People {
public People(){
System.out.println("无参构造函数");
}
public People(int a){
System.out.println("含参构造函数");
}
public static void main(String[] args) throws Exception {
String className = "testt.People";
Class cla = Class.forName(className);
Class[] classes = new Class[]{int.class}; //参数类型数组
Constructor cons = cla.getConstructor(classes);
Object obj = cons.newInstance(new Integer(1));
System.out.println(obj.getClass());
}
}
通过Field类使用指定字段名取出实例对应字段的值如下:
public class People {
public String name = "people";
public static void main(String[] args) throws Exception {
String className = "testt.People";
String fieldName = "name";
Class cla = Class.forName(className);
Object obj = cla.newInstance();
Field field = cla.getDeclaredField(fieldName);
Object str = (String)field.get(obj);
System.out.println(str);
}
}
为了方便理解,我把api粘过来
分别是Class.getConstructor,Constructor.newInstance,Class.getDeclaredField