Java反射的核心是 java.lang.reflect 包,该包提供了一组类和接口,用于在运行时获取类的信息并操作类的成员,主要涉及的类包括 Class 、 Field 、 Method 和 Constructor 。
1. 获取字节码对象(Class)
有三种方式获取:
- Class这个类里面的静态方法forName(“全类名”)(最常用)
- 通过class属性获取
- 通过对象获取字节码文件对象
示例:
// 方式1:使用对象的 .class 属性MyClass obj1 = new MyClass();Class<?> clazz1 = obj1.getClass();// 方式2:使用类的 .class 属性Class<?> clazz2 = MyClass.class;// 方式3:使用 Class.forName() 方法//Class.forName("类的全类名"): 全类名 = 包名 + 类名Class<?> clazz3 = Class.forName("com.test.MyClass");
2. 获取构造方法对象(Constructor)
基本方法介绍
方法名 | 说明 |
---|---|
Constructor<?>[] getConstructors() | 获得所有的构造(只能public修饰) |
Constructor<?>[] getDeclaredConstructors() | 获得所有的构造(包含私有方法) |
Constructor getConstructor(Class<?>… parameterTypes) | 获取指定构造(只能public修饰) |
Constructor getDeclaredConstructor(Class<?>… parameterTypes) | 获取指定构造(包含私有方法) |
示例:
//获取类对象
Class clazz = MyClass.class;//所有构造方法
Constructor[] constructors1 = clazz.getConstructors();//获取所有构造(带私有的)
Constructor[] constructors2 = clazz.getDeclaredConstructors();//获取指定的空参构造
Constructor con1 = clazz.getConstructor();
//获取具有String和int参数的构造方法对象
Constructor con2 = clazz.getConstructor(String.class,int.class);//获取指定的构造(所有构造方法都可以获取到)
Constructor con3 = clazz.getDeclaredConstructor();
Constructor con4 = clazz.getDeclaredConstructor(String.class);
3. 根据构造方法对象来创建类实例对象
关键方法:newInstance()
//获取类对象
Class clazz = Class.forName("com.test.MyClass");
//1.获取空参的构造方法对象
Constructor con1 = clazz.getConstructor();
//创建实例对象
MyClass instance1 = (MyClass) con1.newInstance();//2.获取有参构造方法对象(所有)
Constructor con2 = clazz.getDeclaredConstructor(String.class, int.class);
//临时修改构造方法的访问权限(暴力反射)
con2.setAccessible(true);
//直接创建实例对象
MyClass instance2= (MyClass) con2.newInstance("zhangsan", 23);
4. 获取成员变量对象并操作
基本方法介绍
方法名 | 说明 |
---|---|
Field[] getFields() | 返回所有成员变量对象的数组(只能拿public的) |
Field[] getDeclaredFields() | 返回所有成员变量对象的数组,存在就能拿到(包含私有) |
Field getField(String name) | 返回单个成员变量对象(只能拿public的) |
Field getDeclaredField(String name) | 返回单个成员变量对象,存在就能拿到(包含私有) |
void set(Object obj, Object value) | 赋值 |
Object get(Object obj) | 获取值 |
示例:
//原对象
MyClass obj=new MyClass("张三",18);
//类对象
Class clazz = Class.forName("com.test.MyClass");
//1. 获取所有成员变量的对象(Field对象)只能获取public修饰的
Field[] fields1 = clazz.getFields();
//2. 获取所有成员变量的对象
Field[] fields2 = clazz.getDeclaredFields();
//3.获取单个(根据名字)
Field field3 = clazz.getField("name");
//4. 获取单个成员变量(包括私有)
Field field4 = clazz.getDeclaredField("age");//根据对象修改属性
field3.set(obj,"李四")
//获取新属性
String result = (String)field3.get(s);
System.out.println(result);
5. 获取成员方法对象和操作
基本方法介绍
方法名 | 说明 |
---|---|
Method[] getMethods() | 返回所有成员方法对象的数组(只能拿public的包含父类方法) |
Method[] getDeclaredMethods() | 返回所有成员方法对象的数组,存在就能拿到(包括私有,只能是本类方法) |
Method getMethod(String name, Class<?>… parameterTypes) | 返回单个成员方法对象(只能拿public的) |
Method getDeclaredMethod(String name, Class<?>… parameterTypes) | 返回单个成员方法对象,存在就能拿到 (包括私有) |
Object invoke(Object obj, Object… args) | 根据对象运行方法 |
示例:
Class clazz = Class.forName("com.test.MyClass");
//可以获取**父类**中public修饰的方法
Method[] methods1 = clazz.getMethods();
//获取包含参数的
Method methods2 = clazz.getMethod("show",String.class);
//……其他类似//执行操作
//原对象
MyClass obj=new MyClass();
//如果方法没有返回值,则不需要接收
String result = (String) methods2.invoke(obj, "hello java");
System.out.println(result);
上一篇:了解Java反射原理