什么是反射?
在程序运行的过程中,通过Class对象得到类中的信息构造方法,成员变量,成员方法,并操作他们.
反射的应用场景?
常见的有: idea的智能提示、框架等(通过反射技术对象类进行了解剖得到了类的所有成员。)
使用反射操作类成员的前提
要获得该类字节码文件对象,就是Class对象
三种获取Class对象的方式
类名.class对象.getClass()Class.forName(类全名); 注意: 这三种方式获取的是同一个Class对象提供一个Employee类
public class Employee { private String name; private int age; public String weight; public double height; private int sleep(int hour) { System.out.println("睡了" + hour + "小时"); return hour * 2; } } //省略getset构造方法获取class
@Test public void test01() throws ClassNotFoundException { // 类名.class Class<Employee> cls1 = Employee.class; System.out.println("cls1 = " + cls1); // 对象.getClass() Employee e = new Employee(); Class<? extends Employee> cls2 = e.getClass(); System.out.println("cls2 = " + cls2); // Class.forName(类全名); // 类全名就是: 包名.类名 Class<?> cls3 = Class.forName("com.bean.Employee"); System.out.println("cls3 = " + cls3); System.out.println(cls1 == cls2); System.out.println(cls1 == cls3); }Class类中的方法:
String getName(); 获取类全名 com.bean.EmployeeString getSimpleName(); 获取类名 EmployeenewInstance(); 创建对象 public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Class<?> cls = Class.forName("com.bean.Employee"); // String getName(); System.out.println(cls.getName()); // com.itheima.bean.Employee // String getSimpleName(); System.out.println(cls.getSimpleName()); // Employee Object o = cls.newInstance(); // 使用无参构造创建对象 System.out.println(o); // com.bean.Employee@64c64813 }1.Constructor类作用:
表示类中的构造方法
2.如何得到public的Constructor对象:
1.得到这个类的Class对象 2.通过Class对象获取public构造方法
3.Constructor类的方法:
Object newInstance(); 通过构造方法创建对象
4.基本数据类型与引用数据类型的Class对象
Integer.class != int.class
5.获取public的构造方法?
getConstructors: 获取所有的public的构造方法 getConstructor: 获取一个public的构造方法
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { // 1.得到这个类的Class对象 Class<?> cls = Class.forName("com.bean.Employee"); // 2.通过Class对象获取public构造方法 // getConstructors: 获取所有的public的构造方法 Constructor<?>[] cs = cls.getConstructors(); for (Constructor<?> c : cs) { System.out.println("c = " + c); } System.out.println("------------"); // getConstructor: 获取一个public的构造方法 Constructor<?> c1 = cls.getConstructor(); System.out.println("c1 = " + c1); // Object newInstance(); 通过构造方法创建对象 Object o = c1.newInstance(); System.out.println("o = " + o); Constructor<?> c2 = cls.getConstructor(String.class, int.class); System.out.println("c2 = " + c2); Object o2 = c2.newInstance("凤姐", 18); System.out.println("o2 = " + o2); }通过反射获取声明的Constructor
只要类中有的,不管权限
1.如何得到声明的Constructor
1.获取Class对象 2.通过Class对象获取声明的Constructor
2.Declared的规律
没有Declared获取public的有Declared获取声明的3.对私有构造方法我们在使用之前调用
dc1.setAccessible(true); // 设置可访问为true
4.如何得到声明的Constructor?
getDeclaredConstructors: 获取所有声明的构造方法getDeclaredConstructor: 获取一个声明的构造方法 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { // 1.获取Class对象 Class<?> cls = Class.forName("com.bean.Employee"); // 2.通过Class对象获取声明的Constructor // Declared:表示声明的 // getDeclaredConstructors: 获取所有声明的构造方法 Constructor<?>[] dcs = cls.getDeclaredConstructors(); for (Constructor<?> dc : dcs) { System.out.println("dc = " + dc); } System.out.println("-------------"); // getDeclaredConstructor: 获取一个声明的构造方法 Constructor<?> dc1 = cls.getDeclaredConstructor(String.class); System.out.println("dc1 = " + dc1); // 暴力反射 dc1.setAccessible(true); // 设置可访问为true Object obj = dc1.newInstance("凤姐"); // IllegalAccessException: 非法访问异常 System.out.println("obj = " + obj); Constructor<?> dc2 = cls.getDeclaredConstructor(int.class); System.out.println("dc2 = " + dc2); }1.Method类作用
表示类中的方法
2.如何得到Method对象
1.获取Class对象 2.通过Class对象获取Method
getMethods: 获取所有public的方法(包含父类的)getMethod: 获取一个public的方法getDeclaredMethods: 获取所有声明的方法getDeclaredMethod: 获取一个声明的方法3.Method类中的方法
Object invoke(Object obj, Object… args): 执行, 可以调用这个方法Object obj: 调用方法的对象Object… args: 调用方法的参数返回值Object: 方法的返回值3.Method如何执行
invoke
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { // 1.获取Class对象 Class<?> cls = Class.forName("com.bean.Employee"); Employee e = new Employee(); // 2.通过Class对象获取Method // getMethods: 获取所有public的方法(包含父类的) Method[] ms = cls.getMethods(); for (Method m : ms) { System.out.println("m = " + m); } System.out.println("-------------"); // getMethod: 获取一个public的方法 Method m1 = cls.getMethod("setName", String.class); System.out.println("m1 = " + m1); // Object invoke(Object obj, Object... args): 执行, 可以调用这个方法 // Object obj: 调用方法的对象 // Object... args: 调用方法的参数 // 返回值Object: 方法的返回值 Object r1 = m1.invoke(e, "凤姐"); System.out.println("返回值1: " + r1); // null System.out.println("e = " + e); System.out.println("----------"); // getDeclaredMethods: 获取所有声明的方法 Method[] dms = cls.getDeclaredMethods(); for (Method dm : dms) { System.out.println("dm = " + dm); } System.out.println("-----------"); // getDeclaredMethod: 获取一个声明的方法 Method m2 = cls.getDeclaredMethod("sleep", int.class); System.out.println("m2 = " + m2); m2.setAccessible(true); Object r2 = m2.invoke(e, 10); System.out.println("返回值2: " + r2); }1.Field类的作用:
表示类中的成员变量
2.如果获取Field:
1.获取Class对象 2.通过Class对象获取Field
3.Field的操作:
给成员变量赋值基本数据类型: setXxx setInt,setDouble引用数据类型: set获取成员变量的值
基本数据类型: getXxx getInt,getDouble引用数据类型: get4.如何获取Field?
getFields: 获取所有public的成员变量getField: 获取一个public的成员变量getDeclaredFields: 获取所有声明的成员变量getDeclaredField: 获取一个声明的成员变量 public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException { // 1.获取Class对象 Class<?> cls = Class.forName("com.bean.Employee"); Object obj = cls.newInstance(); // 2.通过Class对象获取Field // getFields: 获取所有public的成员变量 Field[] fs = cls.getFields(); for (Field f : fs) { System.out.println("f = " + f); } System.out.println("-----------"); // getField: 获取一个public的成员变量 Field f1 = cls.getField("weight"); System.out.println("f1 = " + f1); // 赋值 f1.set(obj, "99KG"); System.out.println("obj = " + obj); // 获取值 Object weight = f1.get(obj); System.out.println("weight = " + weight); System.out.println("-----------"); // getDeclaredFields: 获取所有声明的成员变量 Field[] dfs = cls.getDeclaredFields(); for (Field df : dfs) { System.out.println("df = " + df); } System.out.println("-----------"); // getDeclaredField: 获取一个声明的成员变量 Field f2 = cls.getDeclaredField("age"); System.out.println("f2 = " + f2); f2.setAccessible(true); // 赋值 f2.setInt(obj, 18); System.out.println("obj = " + obj); // 获取值 int age = f2.getInt(obj); System.out.println("age = " + age); Class<?> type = f2.getType(); System.out.println("type = " + type); // type = int }