1- 三种创建字节码文件对象

        * a:Object类的getClass()方法,判断两个对象是否是同一个字节码文件
* b:静态属性class,锁对象
* c:Class类中静态方法forName(),读取配置文件

反射总结

2- 通过字节码文件对象创建该类对象(通过反射获取带参构造方法并使用)

    *a: newInstance()

    *b:  Class类的newInstance()方法是使用该类无参的构造函数创建对象, 如果一个类没有无参的构造函数, 就不能这样创建了,可以调用Class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数然后再调用Constructor类的newInstance("张三",20)方法创建对象

        

  Class clazz = Class.forName("com.th.reflect.Person");
  Constructor[] constructors = clazz.getConstructors();//获取所有的构造方法
Constructor constructor = clazz.getConstructor(Class.String, Class.Integer);//获取固定的有参构造

3- 通过反射获取私有成员变量并使用

     其中使用到的类:

    Class : 获取到字节码文件对象;

            forName();

            getConstructor();

            getField("xxx");                  //只能获取公有的字段

            getDeclaredField("xxx");   //暴力获取私有字段

    Constructor:通过字节码对象获取到构造方法;

            newInstance(param1,param2,......);

    Field : 通过字节码对象获取对象的属性;

            setAccessible(true); //去除私有字段的私有权限

            set(Object o,"value");//修改该对象的该属性的值

            

Class clazz = Class.forName("com.heima.bean.Person");
Constructor c = clazz.getConstructor(String.class,int.class);  //1- 获取有参构造
Person p = (Person) c.newInstance("张三",23);          //2- 通过有参构造创建对象

//因为name属性为私有的,用下面注释掉的代码无法获取
//Field f = clazz.getField("name");                         //3- 获取姓名字段
//f.set(p, "李四");                                   //4- 修改姓名的值
Field f = clazz.getDeclaredField("name");           //5- 暴力反射获取字段
f.setAccessible(true);                               //6- 去除私有权限
f.set(p, "李四");                                               //7- 修改字段值

System.out.println(p);

4- 通过反射获取方法并使用

public static String getClassName() throws IOException {
    String className = null;
    Properties properties = new Properties();
    properties.load(new FileInputStream("config.properties"));
    className = properties.getProperty("className");
    return className;
}

String className = getClassName();
Class clazz = Class.forName(className);
Constructor c = clazz.getConstructor(String.class, Integer.class);
Person p = (Person) c.newInstance("Tom1",26);

//1- 获取非私有无参数无返回值的方法并调用
Method eat = clazz.getMethod("eat");
eat.invoke(p);

//2- 获取私有的无参数无返回值的方法并使用
Method sleep = clazz.getDeclaredMethod("sleep");
sleep.setAccessible(true);
sleep.invoke(p);

//3- 获取有参数的方法
Method eat1 = clazz.getMethod("eat", Apple.class);
eat1.invoke(p,new Apple());

//4- 获取有返回值的方法
Method getNameAndAge = clazz.getMethod("getNameAndAge");
String nameAndAge = (String) getNameAndAge.invoke(p);
System.out.println(nameAndAge);



相关文章:

  • 2021-12-06
  • 2021-09-09
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-10-04
  • 2022-12-23
  • 2021-05-20
  • 2021-06-07
  • 2021-07-23
  • 2021-04-10
相关资源
相似解决方案