什么是反射
简单的来说,就是在程序运行时,获取类所有属性和方法信息
- 成员变量的名称是什么,修饰符是什么,类型是什么
- 方法的返回类型是什么,方法名是什么,抛出了哪些异常,修饰它的注解是什么等等
还可以动态创建一个对象,并且调用它的任意一个方法、访问和修改任意一个属性,包括private修饰的方法和属性。
获得Class对象的三种方法
Child child = new Child();
Class yClass = child.getClass();
Class mClass = Child.class;
Class myClass = Class.forName("reflect.Child");
创建实例对象
Class mClass = Child.class;
// 方法一
Object object = mClass.newInstance();
// 方法二
Constructor constructor = mClass.getConstructor();
Object object = constructor.newInstance();
// 构造带参数的
Constructor constructor = mClass.getConstructor(String.class);
Object object = constructor.newInstance("myname");
获取类的成员变量信息
private static void printFields(Class mClass) {
/**
* getFields()
* 获取public访问权限的变量(本类以及父类的public变量,当然也包括 Object 类)
*/
Field[] publicFields = mClass.getFields();
for (Field field : publicFields) {
getFieldInfo(field);
}
/**
* getDeclaredFields()
* 获取所有本类声明变量(不包括父类的变量)
*/
Field[] selfFields = mClass.getDeclaredFields();
for (Field field : selfFields) {
getFieldInfo(field);
}
}
private static void getFieldInfo(Field field) {
System.out.println("\n变量名:" + field.getName());
System.out.println("类型:" + field.getType().getName());
System.out.println("修饰符:" + Modifier.toString(field.getModifiers()));
System.out.println("is private ?" + Modifier.isPrivate(field.getModifiers()));
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println("该变量的注解:" + annotation.annotationType().getName());
}
//获取指定注解
Resource resource = field.getAnnotation(Resource.class);
if (resource != null) {
System.out.println("获取指定注解中的参数值:" + resource.name());
}
}
获取类的方法信息
private static void printMethods(Class mClass) {
/**
* getMethods()
* 获取public访问权限的方法(本类以及父类的public方法)
*/
Method[] publicMethods = mClass.getMethods();
for (Method method : publicMethods) {
getMethodInfo(method);
}
/**
* getDeclaredMethods()
* 获取所有本类声明方法(不包括父类的方法)
*/
Method[] selfMethods = mClass.getDeclaredMethods();
for (Method method : selfMethods) {
getMethodInfo(method);
}
}
private static void getMethodInfo(Method method) {
System.out.println("\n方法名:" + method.getName());
System.out.println("返回类型:" + method.getReturnType().getName());
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
System.out.println("参数类型:" + parameter.getType().getName());
}
Class[] exceptionTypes = method.getExceptionTypes();
for (Class c : exceptionTypes) {
System.out.println("异常类型:" + c.getName());
}
Annotation[] annotations = method.getDeclaredAnnotations();
for (Annotation annotation : annotations) {
System.out.println("该方法的注解:" + annotation.annotationType().getName());
}
}
执行方法
private static void invokeMethod(Class mClass) throws
NoSuchMethodException, IllegalAccessException,
InstantiationException, InvocationTargetException {
Method method = mClass.getMethod("childMethod", String.class);
method.invoke(mClass.newInstance(), "invoke this method!");
}
private static void modifyPrivateField() throws
NoSuchFieldException, IllegalAccessException,
InstantiationException, NoSuchMethodException,
InvocationTargetException {
Class mClass = Child.class;
Constructor constructor = mClass.getConstructor(String.class);
Child child = (Child) constructor.newInstance("old name");
Field field = mClass.getDeclaredField("name");
//获取私有变量访问权
field.setAccessible(true);
System.out.println("修改前:" + child.getName());
field.set(child, "new name");
System.out.println("修改后:" + child.getName());
}