“JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。”
这里,先写了一个javaBean类,然后通过反射先了解这个类的属性和方法,再然后通过反射来调用这些方法。
package org.example.reflection;
public class Person {
public String name;
private String sex;
protected Integer age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return this.sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
private void speak() {
System.out.println("I am a person");
}
public void speak(String msg) {
System.out.println(msg);
}
}
package org.example.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
*
* DOC 初步了解反射<br/>
* 前三行代码表示通过三种方法可以获取一个类的类类型<br/>
* 然后通过API,获取这个类的属性和方法,并且打印出来<br/>
*
*/
public class ReflectionBase {
public static void main(String[] args) throws Exception {
// Class clazz=Person.class;
// Class clazz=new Person().getClass();
// 获得类类型
Class clazz = Class.forName("org.example.reflection.Person");
// 获取该类的属性,要获得父类的属性的话,可以使用clazz.getFields();
Field[] fields = clazz.getDeclaredFields();
// 获取该类的方法,要获得父类的方法的话,可以使用clazz.getMehthods();
Method[] methods = clazz.getDeclaredMethods();
// 打印字段信息
for (int i = 0; i < fields.length; i++) {
System.out.println(fields[i].toString());
}
System.out.println("********************");
// 打印方法信息
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
// 打印方法名称
System.out.println(methods[i].toString());
Class<?>[] types = method.getParameterTypes();
// 打印方法的输入参数信息
for (int j = 0; j < types.length; j++) {
System.out.println(types[j]);
}
// 打印方法的返回类型信息
Class<?> returnType = method.getReturnType();
System.out.println(returnType);
}
System.out.println("********************");
// 还可以获取抛出的异常信息和构造器信息
Constructor[] constructors = clazz.getDeclaredConstructors();
for (int i = 0; i < constructors.length; i++) {
System.out.println("name=" + constructors[i].getName());
System.out.println("class=" + constructors[i].getDeclaringClass());
Class[] exceptionTypes = constructors[i].getExceptionTypes();
for (int j = 0; i < exceptionTypes.length; j++) {
System.out.println(exceptionTypes[j]);
}
}
}
}
package org.example.reflection;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
*
*
* DOC 使用反射,类似javaBean的操作<br/>
* 首先获取set方法,然后调用set方法;然后获取get方法,再调用get方法<br/>
* 在整个过程中,我们都没有显示的使用Person类的某个具体实例
*
*/
public class UseReflection {
public static void main(String[] args) throws Exception {
Class clazz = new Person().getClass();
Field[] fields = clazz.getDeclaredFields();
// 先获取每一个属性,然后调用set和get方法
Object person = clazz.newInstance();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
// 将字段名称的首字母改为大写,这符合javaBean的方法名称拼写标准
String fieldName = field.getName().substring(0, 1).toUpperCase()
+ field.getName().substring(1, field.getName().length());
// 获取set方法
Method setMethod = clazz.getDeclaredMethod("set" + fieldName, field.getType());
// 调用set方法
if (fieldName.equals("Name")) {
setMethod.invoke(person, "张三");
} else if (fieldName.equals("Sex")) {
setMethod.invoke(person, "男");
} else {
setMethod.invoke(person, 20);
}
// 获取get方法
Method getMethod = clazz.getDeclaredMethod("get" + fieldName, null);
// 调用get方法
System.out.println(getMethod.invoke(person, null));
// test results:
/**
* 张三<br/>
* 男<br/>
* 20
*/
}
}
}