反射介绍:
Java反射,就是在运行状态中,
- 获取任意类的名称、package信息、所有属性、方法、注解、类型、类加载器等。
- 获取任意对象的属性,并且能改变对象的属性。
- 调用任意对象的方法。
- 判断任意一个对象所属类。
- 实例化任何一个对象。
通过反射我们可以实现动态装配,降低代码的耦合度,实现动态代理。
java的反射过度使用会严重消耗系统资源。
获取字节码对象:
*
* 获取字节码对象(重点)
* */
public class TestPerson {
public static void main(String[] args) throws ClassNotFoundException {
//1.对象名.getClass()方法
Person person = new Person();
Class<? extends Person> aClass = person.getClass();
System.out.println("aClass = " + aClass);
//2.类名.class
Class<Person> bclass = Person.class;
System.out.println("bclass = " + bclass);
//3.class.forName(全类名)重点,
Class<?> ccalss = Class.forName("com.Person");
System.out.println("ccalss = " + ccalss);
}
}
在字节码中获取构造方法:
/*
* 从字节码中获取构造方法
* */
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
//获取person的字节码对象
Class<?> aClass = Class.forName("com.Person");
//通过字节码对象获取构造方法
Constructor<?> constructor1 = aClass.getConstructor();//空参构造
System.out.println("constructor1 = " + constructor1);
//获取满参构造(传入的参数类型)
Constructor<?> constructor2 =
aClass.getConstructor(Integer.class, String.class, String.class);
System.out.println("constructor2 = " + constructor2);
}
}
创建对象:
/*
* 创建对象
* */
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//1.获取字节码对象
Class<?> aClass = Class.forName("com.Person");
//2.获取空参构造
Constructor<?> constructor = aClass.getConstructor();
//3.创建对象(如果是有参构造就要写传入的参数)
Object o = constructor.newInstance();
System.out.println("o = " + o);
//获取满参构造
Constructor<?> constructor1 = aClass.getConstructor(Integer.class, String.class, String.class);
//创建对象
Object o1 = constructor1.newInstance(12, "小白", "信阳");
System.out.println("o1 = " + o1);
}
}
通过字节码获取成员变量:
/*
* 通过字节码对象获取成员变量对象
* */
public class Test04 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class<?> aClass = Class.forName("com.Person");
//知道成员变量
Field name = aClass.getDeclaredField("name");
System.out.println("name = " + name);
//获取所有成员变量,返回数组
Field[] declaredFields = aClass.getDeclaredFields();
//遍历数组
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
}
}
给对象赋值:
/*
* 给对象属性赋值
* */
public class Test05 {
public static void main(String[] args) throws Exception {
//1.
Class<?> aClass = Class.forName("com.Person");
//2.
Constructor<?> constructor = aClass.getConstructor();
//3.
Object o = constructor.newInstance();
System.out.println("o = " + o);
//4.获取name属性对应的值field对象
Field name = aClass.getDeclaredField("name");
//5.暴力反射
name.setAccessible(true);
//6.将jack赋值给0
name.set(o,"jack");//private私有的,传不进去,就要暴力反射
System.out.println(o);
//获取name属性
Object o1 = name.get(o);
System.out.println("o1 = " + o1);
}
}
获取对象成员方法:
/*
* 获取对象成员方法*/
public class Test06 {
public static void main(String[] args) throws Exception{
//1.获取字节码对象
Class<?> aClass = Class.forName("com.Person");
//2.获取成员方法对象
//根据方法名词和参数类型获取 有参数后面就要跟参数类型
Method getName = aClass.getMethod("setName",String.class);
System.out.println("getName = " + getName);
//获取所有成员方法
Method[] methods = aClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
}
}
调用对象方法:
*调用对象方法*/
public class Test07 {
public static void main(String[] args) throws Exception{
Class<?> aClass = Class.forName("com.Person");
Constructor<?> constructor = aClass.getConstructor();
Object o = constructor.newInstance();
//掉调用show方法, 如果有参数
Method show = aClass.getMethod("show",Integer.class);
//执行方法,有参数才会有第二个参数
show.invoke(o,6);
}
}