1.概述
反射,JAVA提供的一种在运行时获取类的信息并动态操作类的能力。JAVA反射允许我们在运行时获取类的属性、方法、构造函数等信息,并能够动态地操作它们。
2.获取Class对象
理论上来说JAVA反射最底层是基于class文件,JAVA提供了对class文件的运行时描述——即各个类的Class对象,JVM会为每个加载进来的class文件维护一个Class对象,这个Class对象叫做运行时类型信息,记录着对应类的所有相关的信息。
Class对象的获取方式:
1.通过Object类来获取
Class<?> classType1=e.getClass();
2.通过Class类来获取
3.API
3.1.实例化对象
JAVA中有四种方式实例化对象:
- new
- clone
- 序列化
- 反射
利用反射实例化对象:
实体类:
public class People { private String name; private String age; public void say(){ System.out.println("my name is "+name+"\t"+age+" years old"); } }
实例化:
try { //方式1 People people = (People) Class.forName("com.eryi.People").newInstance(); //方式2 // Constructor<People> constructor=People.class.getConstructor(); // People people= constructor.newInstance(); people.say(); } catch (Exception e) { e.printStackTrace(); }
3.2.方法
JAVA提供Method类型来表示方法,Class类中方法相关的API如下:
classType.getMethods() | 获取当前类以及父类的public方法 |
classType.getDeclareMethods() | 获取当前类的所有方法 |
classType. getMethod(String name.Class<?>... parameterTypes) | 获得当前类以及父类指定的public方法 |
classType. getDeclaredMethod(String name,Class<?>... parameterTypes) | 获得当前类的指定的Method |
代码示例:
注意:通过反射访问私有方法时要关闭安全检查。
//获取类对象 Class<?> classType=Class.forName("reflection.emplee"); //调带参构造实例化 Constructor<?> constructor2=classType.getConstructor(new Class[]{String.class,int.class}); emplee e3=(emplee)constructor2.newInstance(new Object[]{"张三",30}); //获得指定方法 Method method1=classType.getDeclaredMethod("toString",new Class[]{}); String result1=(String)method1.invoke(e3, new Object[]{}); System.out.println(result1); //获得全部方法(包括私有) Method[] methods=classType.getDeclaredMethods(); for (Method m : methods) { System.out.println("方法名:"+m.getName()+"\t"+"返回值类型:"+m.getReturnType()); } //调用私有方法 Method method2=classType.getDeclaredMethod("getName",new Class[]{}); //关闭安全检查 method2.setAccessible(true); String result2=(String)method2.invoke(e3, new Object[]{}); System.out.println(result2);
3.3.属性
JAVA提供Method类型来表示属性,Class类中与属性相关的API如下:
classType. getFields() | 获得当前类以及超类的public Field |
classType. getDeclaredFields() | 获得当前类申明的所有Field |
classType. getField(String name) | 获得当前类以及超类指定的public Field |
classType. getDeclaredField(String name) | 获得当前类申明的指定的Field |
field.set(Object obj, Object value) | 通过反射动态设定Field的值 |
Object obj = field.get(Object obj) | 通过反射动态获取Field的值 |
代码示例:
//获取class对象所指定的属性,包括私有的 Field field = classType.getDeclaredField("name"); //关闭安全检查 field.setAccessible(true);"李四") ; field.set(employeeSystem.out.println(field.get (employee)) ;