反射Reflection
反射在平时业务代码时代码中使用的比较少,但是却常常出现在一些框架的源码中。这里记录总结一下与反射相关的类及其使用方法。
反射相关的类
Class类与java.lang.reflect类库一起对反射的概念进行了支持(出自Java编程思想,重新捡起)。与反射相关的类有:
java.lang.Class | Class类 |
java.lang.reflect.Constructor | 构造器 |
java.lang.reflect.Field | 成员变量 |
java.lang.reflect.Method | 方法 |
java.lang.reflect.Modifier | 修饰符 |
使用方法
ApplicationMain.java
package com.tt;
import com.tt.reflection.ReflectionUtil;
import com.tt.reflection.TestClass;
public class ApplicationMain {
public static void main(String[] args) {
// 打印类方法的信息
System.out.println(ReflectionUtil.getClassMethodInfo(TestClass.class));
// 打印类成员变量的信息
System.out.println(ReflectionUtil.getClassFieldInfo(TestClass.class));
// 执行类的printHello()
ReflectionUtil.executeMethod(TestClass.class, "printHello", new Object[0]);
// 执行类的printHello(String,String)
ReflectionUtil.executeMethod(TestClass.class, "printHello", new String[]{"1","2"});
}
}
TestClass.java
package com.tt.reflection;
public class TestClass {
private String name;
public int age;
@Deprecated
int name3;
public static final String TAG = "1";
protected int name4;
public void printHello() {
System.out.println("printHello");
}
public void printHello(String a, String b) {
System.out.println("printHello-->a:" + a + ", "+ "b:" + b);
}
@Override
public String toString() {
return super.toString();
}
public String getName() {
return name;
}
}
ReflectionUtil.java
package com.tt.reflection;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
public class ReflectionUtil {
/**
* 获取类成员变量的详细信息
*/
public static String getClassFieldInfo(Class<?> c) {
StringBuilder sb = new StringBuilder();
Field[] fields = c.getDeclaredFields(); // 获取类所有的成员变量
for (Field field : fields) {
sb.append(Modifier.toString(field.getModifiers()) + " "); // 获取成员变量的修饰符,如public
sb.append(field.getType().getSimpleName() + " "); // 获取成员变量的类型,如int
sb.append(field.getName() + "\n"); // 获取成员变量的名字,如age
sb.append("\n");
}
return sb.toString();
}
/**
* 获取类方法的详细信息
*/
public static String getClassMethodInfo(Class<?> c) {
StringBuilder sb = new StringBuilder();
Method[] methods = c.getDeclaredMethods(); // 获取类所有的方法
for (Method method : methods) {
sb.append(Modifier.toString(method.getModifiers()) + " "); // 获取方法的修饰符,如public
sb.append(method.getReturnType().getSimpleName() + " "); // 获取方法返回值的类型,如int
sb.append(method.getName() + " "); // 获取方法的名字,如getName()
sb.append("(");
Parameter[] parameters = method.getParameters(); // 获取方法所有参数
for (Parameter parameter : parameters) {
sb.append(parameter.getType().getSimpleName() + ","); // 获取方法参数的类型
}
if (parameters.length > 0) {
sb.deleteCharAt(sb.length() - 1);
}
sb.append(")\n\n");
}
return sb.toString();
}
/**
* 执行类的方法
* @param method String类型的方法名
* @param params 方法参数
*/
public static Object executeMethod(Class<?> c, String method, Object[] params) {
try {
Class<?>[] types;
int length = params.length;
if (length == 0) {
types = new Class[]{};
}else {
types = new Class[params.length];
for (int i = 0; i < length; i++) {
Object o = params[i];
types[i] = o.getClass(); // 获取参数的类型
}
}
Method me = c.getMethod(method, types); // 获取类的方法
// 执行类的方法(注意这里的c.newInstance()只能调用无参构造器)
return me.invoke(c.newInstance(), params);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return null;
}
}