【java】反射机制
目录
一、什么是反射机制
- 1.将类的各个组成部分封装为其他对象
二、反射的优点
- 1.可以在程序运行的过程中操作对象
- 2.可以解耦,提高程序的可扩展性
三、获取Class对象的方式
说明: 同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个
3.1 Class.forName(全类名)
- 1.将字节码文件加载进内存,返回Class对象
- 2.多用于配置文件,将类名定义在配置文件中,读取文件,加载类
3.2 通过类名的class属性
- 1. 类名.class
- 2. 多用于参数的传递
3.3 对象.getClass()
- 1. getClass()方法在Object类中定义的
- 2. 多用于对象的获取字节码的方式
四、Class对象功能
4.1 获取功能
- 1.获取成员变量
// 获取所有公开的成员变量,包括继承变量
Field[] fields = clazz.getFields();
// 获取本类定义的成员变量,包括私有,但不包括继承的变量
Field[] declaredFields = clazz.getDeclaredFields();
// 获取指定变量
Field field = clazz.getField("name");
Field declaredField = clazz.getDeclaredField("name");
- 2.获取构造方法
//获取公开的构造方法
Constructor<?> constructor = clazz.getConstructor(String.class);
//获取所有的公开的构造方法
Constructor<?>[] constructors = clazz.getConstructors();
//获取所有的构造方法,包括私有
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(int.class, String.class);
- 3.获取成员方法
//获取所有可见的方法,包括继承的方法
Method[] methods = clazz.getMethods();
//获取本类定义的的方法
Method test = clazz.getMethod("test", String.class);
//获取本类定义的的方法,包括私有,不包括继承的方法
Method[] declaredMethods = clazz.getDeclaredMethods();
Method method = clazz.getDeclaredMethod("test", int.class, String.class);
4.2 Field成员变量
- 1.设置值
void set(Object obj, Object value);
- 2.获取值
get(Object obj);
- 3.忽略访问权限修饰符的安全检查
// 暴力反射
setAccessible(true);
- 4.示例
// 反射调用成员变量
// 获取变量
Field age = clazz.getDeclaredField("age");
// 使私有成员允许访问
age.setAccessible(true);
// 为指定实例的变量赋值,静态变量,第一参数给null
age.set(o,22);
// 访问指定实例变量的值,静态变量,第一参数给null
age.get(o);
4.3 Constructor构造方法
- 1.创建对象
T newInstance(Object ...initargs)
- 2.如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
//执行无参构造创建对象
Object o = clazz.newInstance();
//执行有参构造创建对象
clazz.newInstance();
clazz.getConstructor(int.class,String.class);//获取构造方法
4.4 Method方法对象
- 1.执行方法
Object invoke(Object obj,Object... args)
- 2.获取方法名称
String getName获取方法名
- 3.示例
// 反射调用成员方法
Method m = clazz.getDeclaredMethod("test",String.class);
m.setAccessible(true);//使私有方法允许被调用
m.invoke(o, "你好");//让指定实例来执行该方法
五、示例
package learning.reflect;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;/* @Author wangyouhui* @Description 反射*/
public class ReflectTest {private String name;private int age;public ReflectTest(int age, String name){this.name = name;this.age = age;}public static void main(String[] args) throws Exception {Class<?> clazz = Class.forName("learning.reflect.ReflectTest");//获取包名String packageName = clazz.getPackage().getName();//获取类名String simpleName = clazz.getSimpleName();//获取完整类名String name = clazz.getName();//获取成员变量定义信息// 获取所有公开的成员变量,包括继承变量Field[] fields = clazz.getFields();// 获取本类定义的成员变量,包括私有,但不包括继承的变量Field[] declaredFields = clazz.getDeclaredFields();Field field = clazz.getField("name");Field declaredField = clazz.getDeclaredField("name");//获取构造方法定义信息//获取公开的构造方法Constructor<?> constructor = clazz.getConstructor(String.class);//获取所有的公开的构造方法Constructor<?>[] constructors = clazz.getConstructors();//获取所有的构造方法,包括私有Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(int.class, String.class);//获取方法定义信息//获取所有可见的方法,包括继承的方法Method[] methods = clazz.getMethods();//获取本类定义的的方法Method test = clazz.getMethod("test", String.class);//获取本类定义的的方法,包括私有,不包括继承的方法Method[] declaredMethods = clazz.getDeclaredMethods();Method method = clazz.getDeclaredMethod("test", int.class, String.class);//反射新建实例//执行无参构造创建对象Object o = clazz.newInstance();//执行有参构造创建对象clazz.newInstance();clazz.getConstructor(int.class,String.class);//获取构造方法// 反射调用成员变量// 获取变量Field age = clazz.getDeclaredField("age");// 使私有成员允许访问age.setAccessible(true);// 为指定实例的变量赋值,静态变量,第一参数给nullage.set(o,22);// 访问指定实例变量的值,静态变量,第一参数给nullage.get(o);// 反射调用成员方法Method m = clazz.getDeclaredMethod("test",String.class);m.setAccessible(true);//使私有方法允许被调用m.invoke(o, "你好");//让指定实例来执行该方法}
}