反射
可以将一个正在运行的类通过这个Class文件的对象,可以直接获取类内部的所有方法和成员变量。
- 获取Class文件对象
1.通过对象获取
2.通过类获取
3.通过Class中的静态方法获取(Class.forName())
比如说我们创建了一个Person类
// 通过对象获取
Person person = new Person();
// 获取Person类的 Class文件对象
Class<? extends Person> c1 = person.getClass();
// 全类名
System.out.println(c1);
// 通过类获取
Class<Person> c2 = Person.class;
System.out.println(c2\);
// 常用(只需一个字符串 就能获取该类的Class对象)
// 注意参数要填全类名 包名+类名
Class<?> c3 = Class.forName("xx.Person");
System.out.println(c3);
- 通过Class文件对象获取类中构造方法
Class<?> c = Class.forName("xx.Person");
// 获取所有public公有的构造方法
Constructor<?>[] constructors = c.getConstructors();
// 遍历
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
// 获取单个的构造方法
Constructor<?> constructor2 = c.getConstructor();
// 利用该构造方法创建对象
Object newInstance = constructor2.newInstance();
System.out.println(newInstance);
// 有参构造创建对象 参数是 参数类的文件类型
Constructor<?> constructor = c.getConstructor(String.class, int.class);
Object newInstance2 = constructor.newInstance("hanhan", 29);
System.out.println(newInstance2);
/*
* 通过Class文件对象快速创建对象
* 前提:
* 1.类必须用public
* 2.必须提供无参的构造方法
* 3.该无参的构造方法必须是public
*/
// 快速创建对象(直接使用类中的无参构造方法创建)
Object object = c.newInstance();
System.out.println(object);
// 获取类中所有的构造方法(包括私有)
Constructor<?>[] constructors = c.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
// 获取私有的构造方法
Constructor<?> constructor = c.getDeclaredConstructor(int.class, String.class);
// 打开私有方法使用的权限
constructor.setAccessible(true);
Person newInstance = (Person)constructor.newInstance(12, "HANHAN");
System.out.println(newInstance);
// 获取所有成员变量(公开的)
Field[] fields = c.getFields();
for (Field field : fields) {
System.out.println(field);
}
// 单独获取指定的成员变量
Field field = c.getField("name");
System.out.println(field);
// 通过反射给这个属性赋值
field.set(object, "憨憨");
System.out.println(object);
// 获取私有成员变量并打印
Field field2 = c.getDeclaredField("age");
field2.setAccessible(true);
field2.set(object, 14);
System.out.println(object);
- 获取成员方法
Class<?> c = Class.forName("XX.Person");
// 获取类中所有的公开方法(包括父类的)
Method[] methods = c.getMethods();
for (Method method : methods) {
System.out.println(method);
}
// 获取指定的成员方法
/*
* 参数1.获取的属性的名字
* 参数2.获取方法的参数的Class类型
*
*/
Method method = c.getMethod("eat");
System.out.println(method);
Object object = c.newInstance();
// 调用方法
/*
* 参数1.调用该方法的对象
* 参数2.调用该方法 要传入的参数
*/
Object invoke = method.invoke(object);
System.out.println(invoke);
Method method2 = c.getMethod("speak", String.class);
Object invoke2 = method2.invoke(object, "English");
System.out.println(invoke2);
Method declaredMethod = c.getDeclaredMethod("play", String.class);
declaredMethod.setAccessible(true);
System.out.println(declaredMethod);
Object invoke3 = declaredMethod.invoke(object, "renqi");
System.out.println(invoke3);