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);