Java 反射
Class 类类型
理解java反射,有助于深入理解java面向对象思想,即万事万物皆对象(除了基本数据类型和静态成员变量)
- 类是对象,是 java.lang.Class 的对象,称 Class 为类的类类型
- 方法是对象,是 java.lang.reflect.Method 的对象
- 成员变量是对象,是 import java.lang.reflect.Field 的对象
- 构造方法是对象, 是 java.lang.reflect.Constructor 的对象
- void 也是对象
获取类类型的三种方法
// 1、通过.class方式获取
Class c1 = User.class;
// 2、通过对象获取
User user = new User();
Class c2 = user.getClass();
// 3、通过类路径获取
Class c3 = null;
try {
c3 = Class.forName("com.reflact.bean.User");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
动态加载类及使用类类型创建对象
new方式在编译时加载所有可能用到的类(静态加载类),如果存在一个使用到的类未声明,则编译报错,而编译通过所加载的类不一定都会被用到
而动态加载类在编译时不加载所有类,而在编译后加载类,如果存在一个使用到的类未声明,则编译不会报错,可以在用到时加载
Class c = null;
User u = null;
try {
// 动态加载类
c = Class.forName("com.reflact.bean.User");
// 使用类类型创建对象
u = (User) c.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
使用类类型获取该类的信息
类名
c.getName()
方法对象(方法名、返回值的类类型、参数的类类型)
Method[] methods = c.getMethods(); // 所有的
// Method[] methods = c1.getDeclaredMethods(); // 获取自己的方法,不包含继承而来的
for(int i = 0, j = methods.length; i < j; i++){
// 方法名
System.out.println(methods[i]);
// 返回值的类类型
System.out.println(methods[i].getReturnType());
// 参数的类类型
Class[] params = methods[i].getParameterTypes();
}
成员变量对象(类类型)
// Field[] fields = c1.getFields(); // public 的
Field[] fields = c.getDeclaredFields(); // 所有的
for(int i = 0, j = fields.length; i < j; i++){
// 成员变量名
System.out.println(fields[i].getName());
// 成员变量类类型
System.out.println(fields[i].getType());
}
构造方法对象(方法名、参数的类类型)
Constructor[] constructors = c.getConstructors();
for(int i = 0, j = constructors.length; i < j; i++){
// 参数的类类型
Class[] params = constructors[i].getParameterTypes();
}
方法的反射操作
Method method = null;
try {
// 根据方法名和参数列表类类型,使用该类类型获取到某一方法,传入方法名和参数类类型列表
method = c.getMethod("setUserName", String.class);
// 反射操作,传入对象实例和参数列表
method.invoke(u, "Franco Liang");
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}