反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,通过反射,我们可以动态获取一个类中的属性和方法,大大增加了程序的扩展性。
反射中主要用的类:
(1)java.lang.Class 对象建模的类的类型,存放调用类型的表现形式。该类定义了返回构造函数,成员变量,成员属性等一系列方法。
(2)java.lang.reflect.Constructor 构造函数
(3)java.lang.reflect.Field 成员变量
(4)java.lang.reflect.Mothed 成员方法
1 反射获取方法说明
1.1 反射机制获取类有三种方法,我们来获取cjr.reflect.Person类型
- Classc1 = Employee.class;
- Classc2 = new Employee().getClass();
- Classc3 = Class.forName("cjr.reflect.Person");
注:一般情况下, 我们用的是第三种方式, 通过类名进行获取,类名需包含包名,否则会报java.lang.ClassNotFoundException异常
1.2 获取构造并实例化
(1)
调用无参构造函数
Object object1 = class1.newInstance();(2) 实例化带参数的构造函数
Constructor<?> constructor = class1.getConstructor(String.class,int.class);Object object2 = constructor.newInstance("陈佳仁",20);//调用有参构造函数实例化对象
1.3 成员变量
(1)获取成员变量
Field fieldName = class1.getField("name");//获取成员变量,无法获取私有的(private)Field fieldAge = class1.getDeclaredField("age");//可获取所有类型的成员变量,包括private
(2)设置成员变量
fieldAge.set(object2, 21);//设置成员变量属性值
(3)获取成员变量值
fieldAge.get(object2)
注:要调用私有的Field,要调用getDeclaredField()方法,要操作private修饰的变量,需设置其可访问属性为True,
fieldAge.setAccessible(true); 下面私有成员方法也类似
1.4 成员方法
(1)获取无参构造函数并调用
Method method = class1.getMethod("run");//调用无参方法method.invoke(object2);
(2)调用静态方法
Method methodStatic = class1.getMethod("staticRun");//调用静态方法methodStatic.invoke(object2);
(3)调用私有含参方法
Method runParamenters = class1.getDeclaredMethod("runParamenters", String.class);runParamenters.setAccessible(true);System.out.println(runParamenters.invoke(object2, "abcd"));
(4)调用可变参数方法
Method methodVarableParas = class1.getMethod("varableRun", String[].class);String[] params = {"Work", "fuck","more", "faster"};methodVarableParas.invoke(object2,(Object)params);
2 代码案例
package cjr.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
String path = "cjr.reflect.Person";
Class<?> class1 = Class.forName(path);
//1 构造函数Constructor
System.out.println("============1 构造函数Constructor============");
Object object1 = class1.newInstance();//调用无参构造函数
Constructor<?> constructor = class1.getConstructor(String.class,int.class);
Object object2 = constructor.newInstance("陈佳仁",20);//调用有参构造函数实例化对象
//2 成员变量Field
System.out.println("============2 成员变量Field================");
Field fieldName = class1.getField("name");//获取成员变量,无法获取私有的(private)
Field fieldAge = class1.getDeclaredField("age");//可获取所有类型的成员变量,包括private
System.out.println(fieldName.get(object2));
fieldAge.setAccessible(true);//private成员属性必须设置可访问状态为true,才可以操作。否则会报java.lang.IllegalAccessException 异常
System.out.println(fieldAge.get(object2));
fieldName.set(object2, "chenjiaren");
fieldAge.set(object2, 21);
System.out.println(fieldName.get(object2) + " : " + fieldAge.get(object2));
//3 成员方法
System.out.println("============3 成员方法Method================");
Method method = class1.getMethod("run");//调用无参方法
method.invoke(object2);
Method methodStatic = class1.getMethod("staticRun");//调用静态方法
methodStatic.invoke(object2);
Method runParamenters = class1.getDeclaredMethod("runParamenters", String.class);//调用私有含参方法
runParamenters.setAccessible(true);
System.out.println(runParamenters.invoke(object2, "abcd"));
Method methodVarableParas = class1.getMethod("varableRun", String[].class);//调用可变参数方法
String[] params = {"Work", "fuck","more", "faster"};
methodVarableParas.invoke(object2,(Object)params);
}
}
class Person {
public String name;
private int age;
public Person() {
super();
System.out.println("Person Constructor ...");
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
System.out.println("Person Constructor ... "+ this.name + " : " + this.age );
}
public void run(){
System.out.println("public run .......... " + this.name + " : " + this.age);
}
public static void staticRun(){
System.out.println("static run ..........");
}
private boolean runParamenters(String str){
System.out.println("runParamenters ....... " +str);
return str.length()>5;
}
public void varableRun(String ...args){
for(String str : args){
System.out.println("varableStringRun === "+ str);
}
}
}
运行结果:
============1 构造函数Constructor============
Person Constructor ...
Person Constructor ... 陈佳仁 : 20
============2 成员变量Field================
陈佳仁
20
chenjiaren : 21
============3 成员方法Method================
public run .......... chenjiaren : 21
static run ..........
runParamenters ....... abcd
false
varableStringRun === Work
varableStringRun === fuck
varableStringRun === more
varableStringRun === faster
Person Constructor ...
Person Constructor ... 陈佳仁 : 20
============2 成员变量Field================
陈佳仁
20
chenjiaren : 21
============3 成员方法Method================
public run .......... chenjiaren : 21
static run ..........
runParamenters ....... abcd
false
varableStringRun === Work
varableStringRun === fuck
varableStringRun === more
varableStringRun === faster