反射的定义
java 反射机制是在运行状态中,对于任意一个类、任意一个对象,都能知道和调用它的任意方法和属性,这种动态获取信息以及动态调用对象方法的功能成为Java 的反射机制
获取class 对象
【1】Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象(多用于配置文件)
【2】类名.class:通过类名的属性class获取(多用于参数的传递)
【3】对象.getClass():多用于对象的获取字节码方式
同一个字节码文件(*.class)在一次程序的执行过程中,只会被加载一次,无论通过上述哪种方式获取的Class对象!
/**
* 获取类的方式:
* Class.forName
* 类名.class
* 对象.getClass
*/
public static void getClassTest() throws ClassNotFoundException {
Class cls1 = Class.forName("com.zjh.pojo.Person");
Class cls2 = Person.class;
Person p = new Person();
Class cls3 = p.getClass();
System.out.println("cls1:" + cls1 + "\ncls2:" + cls2 + "\ncls3:" + cls3);
System.out.println(cls1 == cls2);//true
System.out.println(cls1 == cls3);//true
//同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
}
Class 对象功能
获取成员变量
- Field[] getFields()
- Field getField(String name)
- Field[] getDeclaredFields()
- Field getDeclaredField(String name)
/**
* 成员变量测试
*/
public static void fieldTest() throws Exception {
Class cls1 = Class.forName("com.zjh.pojo.Person");
//1.Field[] getFields() 获取所有public修饰的成员变量
Field[] fields = cls1.getFields();
for (Field field : fields) {
System.out.println(field);
}
//2.通过成员变量名称获取public修饰的成员变量
Field a = cls1.getField("a");
//3.获取成员变量的值
Person p = new Person();
System.out.println(a.get(p));
//4.设置a的值
a.set(p, "aa");
System.out.println(p.a);
//Field[] getDeclaredFields() 获取任意修饰符的成员变量
Field[] declaredFields = cls1.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
//通过成员变量获取任意修饰符的成员变量
Field fieldName = cls1.getDeclaredField("name");
//忽略访问权限修饰符的安全检查:暴力反射
fieldName.setAccessible(true);
//获取p对象下的name属性值
System.out.println(fieldName.get(p));因为该属性是私有的,所以抛了以下异常:Exception in thread "main" java.lang.IllegalAccessException: Class com.zjh.test.ReflectDemo can not access a member of class com.zjh.pojo.Person with modifiers "private"
//设置p对象下的name属性值
fieldName.set(p, "法外狂徒张三");//因为该属性是私有的,所以抛了以下异常:Exception in thread "main" java.lang.IllegalAccessException: Class com.zjh.test.ReflectDemo can not access a member of class com.zjh.pojo.Person with modifiers "private"
System.out.println(p);
}
获取构造方法
- Constructor<?>[] getConstructors()
- Constructor getConstructor(类<?>… parameterTypes)
- Constructor getDeclaredConstructor(类<?>… parameterTypes)
- Constructor<?>[] getDeclaredConstructors()
public static void constructorTest() throws Exception {
Class cls1 = Person.class;
//获取public 修饰的构造方法
Constructor[] constructors = cls1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
//获取public修饰的构造方法
Constructor constructor = cls1.getConstructor(String.class, int.class);
//根据构造方法创建对象
Object instance = constructor.newInstance("法外狂徒张三", 18);
System.out.println(instance);
//获取任意修饰符的构造方法
Constructor[] declaredConstructors = cls1.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
//获取任意修饰符的构造方法
Constructor constructor1 = cls1.getDeclaredConstructor(String.class);
//暴力破解
constructor1.setAccessible(true);
Object instance1 = constructor1.newInstance("张三弟弟");//因为该构造方法是私有的,所以抛了以下异常Exception in thread "main" java.lang.IllegalAccessException: Class com.zjh.test.ReflectDemo can not access a member of class com.zjh.pojo.Person with modifiers "private"
System.out.println(instance1);
}
获取成员方法
- Method[] getMethods()
- Method getMethod(String name, Class<?>… parameterTypes)
- Method[] getDeclaredMethods()
- Method getDeclaredMethod(String name, Class<?>… parameterTypes)
/**
* 成员方法测试
*
* @throws Exception
*/
public static void methodTest() throws Exception {
Class cls1 = Person.class;
//获取方法
Method[] methods = cls1.getMethods();
for (Method method : methods) {
System.out.println(method);
}
//获取方法
Method play = cls1.getMethod("play");
Method study = cls1.getMethod("study", String.class);
//执行方法
Person person = new Person();
play.invoke(person);
study.invoke(person, "java");
//获取私有方法
//cls1.getDeclaredMethods();
Method playPrivate = cls1.getDeclaredMethod("playPrivate");
playPrivate.setAccessible(true);//暴力破解
playPrivate.invoke(person);//Exception in thread "main" java.lang.IllegalAccessException: Class com.zjh.test.ReflectDemo can not access a member of class com.zjh.pojo.Person with modifiers "private"
}
获取类名name
- String getName()
整合测试demo
/**
* 整合测试
* 在不修改代码的情况下,可以创建任意类,并执行相应的方法
*/
public static void reflectTest() throws Exception {
//通过配置文件读取数据
//1.创建properties对象
Properties properties = new Properties();
//2.加载配置文件
//2.1获取class目录下的配置文件
ClassLoader classLoader = ReflectDemo.class.getClassLoader();
properties.load(classLoader.getResourceAsStream("pro.properties"));
//3.获取类路径即方法名
String className = properties.getProperty("reflect.class.name", "com.zjh.pojo.Person");
String methodName = properties.getProperty("reflect.method", "playPrivate");
//4.加载该类进内存
Class<?> cls1 = Class.forName(className);
//5.创建对象
Object instance = cls1.newInstance();
//6.获取方法并执行
Method method = cls1.getDeclaredMethod(methodName);
method.setAccessible(true);//暴力反射
method.invoke(instance);
}