反射是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类型

1. Classc1 = Employee.class; 
2. Classc2  = new Employee().getClass(); 
3. 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