根据配置文件指定信息,动态创建对象,并执行方法
配置文件 re.properties
classfallpath=com.yzp.Cat
method1=hi1
method2=hi2
method3=hi3
com.yzp.Cat
package com.yzp;
public class Cat {
public int age = 20; // public 成员变量
public static String color = "黑色"; // 静态成员变量
private String name = "100"; // 私有成员变量
public Cat() { // 无参构造
}
private Cat(String name) { // 私有的有参构造
this.name = name;
}
public void hi1() { // 普通方法,无返回
System.out.println("hi 方法执行...");
}
public static void hi2() { // 静态方法
System.out.println("静态方法hi2执行...");
}
private String hi3(String s1, int a) { // 私有的有参有返回方法
System.out.println("hi3 方法执行... s1=" + s1 + " a=" + a);
return s1;
}
}
测试类
package com.yzp;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;
public class MainTest {
public static void main(String[] args) throws Exception {
// 加载配置文件
Properties properties = new Properties();
// properties.load(new FileInputStream("src/main/resources/re.properties"));
// properties.load(new FileInputStream("reflection-test-1/src/main/resources/re.properties")); // 聚合工程需要加上子工程的项目名
properties.load(MainTest.class.getClassLoader().getResourceAsStream("re.properties"));
String classfallpath = properties.getProperty("classfallpath");
String methodName1 = properties.getProperty("method1");
String methodName2 = properties.getProperty("method2");
String methodName3 = properties.getProperty("method3");
// 反射
// 获取 Class 对象
Class<?> cls = Class.forName(classfallpath);
// 获取构造器,如果构造器有参数需传入参数Class类型。getConstructor()只能获取public的构造器,而getDeclaredConstructor能获取本类所有构造器
Constructor<?> noParaConstructor = cls.getDeclaredConstructor();
// 创建对象,如果构造器有参数,需传入参数的Class类型。虽然返回的是Object类型,但实际运行类型已经是创建的具体的类型了,此处可以强转
Object noParaNewInstance = noParaConstructor.newInstance();
// 获取方法对象,传入方法名称,如果方法有参数,需要传入方法参数的Class类型
Method method1 = cls.getMethod(methodName1);
// 执行方法。第一个参数为反射创建出来的这个方法的对象,后面参数为方法的参数。【执行方法的格式: 方法对象.invoke(方法的实例对象,方法参数...)】
method1.invoke(noParaNewInstance);
// 执行静态方法
Method method2 = cls.getMethod(methodName2);
method2.invoke(noParaNewInstance);
// 或 method2.invoke(null);
// 执行私有方法,有参数有返回
Method method3 = cls.getDeclaredMethod(methodName3, String.class, int.class);
// 暴力破解(私有属性都需要暴力破解)
method3.setAccessible(true);
Object method3ReturnResult = method3.invoke(noParaNewInstance, "黑猫警长", 18);
System.out.println("方法hi3返回值:" + method3ReturnResult);
// 获取普通成员变量
Field age = cls.getField("age");
// 获取成员变量的值。 【格式: 成员变量对象.get(成员变量的实例对象)】
Object ageValue = age.get(noParaNewInstance);
System.out.println("age的值:" + ageValue);
// 获取静态成员变量
Field color = cls.getField("color");
// 获取静态成员变量的值。 【格式: 静态成员变量对象.get(成员变量的实例对象或null)】
// Object colorValue = color.get(noParaNewInstance);
Object colorValue = color.get(null);
System.out.println("color的值:" + colorValue);
// 获取私有成员变量
Field name = cls.getDeclaredField("name");
// 暴力破解(私有属性都需要暴力破解)
name.setAccessible(true);
Object nameValue = name.get(noParaNewInstance);
System.out.println("name的值:" + nameValue);
System.out.println("===================");
// 私有构造器,有参数
Constructor<?> hasParadeclaredConstructor = cls.getDeclaredConstructor(String.class);
// 暴力破解(私有属性都需要暴力破解)
hasParadeclaredConstructor.setAccessible(true);
// 创建对象,并传入参数
Object hasParaNewInstance = hasParadeclaredConstructor.newInstance("hi 小猫咪");
// 执行方法
Method method = cls.getMethod(methodName1);
method.invoke(hasParaNewInstance);
}
}