Java 反射(三)-反射操作
反射操作
1.通过反射获取类的结构信息
代码展示
package javareflect.demo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectionUtils {
public static void main(String[] args) throws ClassNotFoundException {
TestApi();
}
public static void TestApi() throws ClassNotFoundException {
//得到Class对象
Class<?> personCls=Class.forName("javareflect.Person");
Field[] declaredFields=personCls.getDeclaredFields();
for (Field declaredField: declaredFields){
System.out.println("本类中所有属性=" + declaredField.getName()
+ " 该属性的修饰符值=" + declaredField.getModifiers()
+ " 该属性的类型=" + declaredField.getType());
}
//getDeclaredMethods:获取本类中所有方法
Method[] methods = personCls.getDeclaredMethods();
for (Method method: methods){
System.out.println("本类中所有方法=" + method.getName()
+ " 该方法的访问修饰符值=" + method.getModifiers()
+ " 该方法返回类型" + method.getReturnType());
//输出当前这个方法的形参数组情况
Class<?>[] parameterTypes = method.getParameterTypes();
for(Class<?> parameterType:parameterTypes){
System.out.println("该方法的形参类型=" + parameterType);
}
}
//getDeclaredConstructors:获取本类中所有构造器
Constructor<?>[] declaredConstructors = personCls.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println("====================");
System.out.println("本类中所有构造器=" + declaredConstructor.getName());
}
}
}
2.通过反射创建对象
代码演示
public class ReflectDemo4 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//1. 先获取到 User 类的 Class 对象
Class<?> userClass = Class.forName("javareflect.User");
//2. 通过 public 的无参构造器创建实例
Object o = userClass.newInstance();
System.out.println(o);
//3. 通过 public 的有参构造器创建实例
Constructor<?> constructor = userClass.getConstructor(String.class);
//3.2 创建实例,并传入实参
Object personObj=constructor.newInstance("lisus");
System.out.println("personObj"+personObj);
//4. 通过非 public 的有参构造器创建实例
//4.1 得到 private 的构造器对象
Constructor<?> constructor1=userClass.getDeclaredConstructor(int.class,String.class);
//暴破【暴力破解】 , 使用反射可以访问 private 构造器/方法/属性, 反射面前,都是纸老虎
constructor1.setAccessible(true);
Object person2=constructor1.newInstance(100,"顷三");
System.out.println("person2"+person2);
}
}
3.通过反射访问类中的成员
代码演示
public class ReflecAccessMethod {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
//1. 得到 Student 类对应的 Class 对象
Class<?> stuClass = Class.forName("javareflect.demo.Student");
//2. 创建对象
Object o = stuClass.newInstance();//o 的运行类型就是 Student
System.out.println(o.getClass());//Student
//3. 使用反射得到 age 属性对象
Field age = stuClass.getField("age");
age.set(o, 88);//通过反射来操作属性
System.out.println(o);//
System.out.println(age.get(o));//返回 age 属性的值
//4. 使用反射操作 name 属性
Field name = stuClass.getDeclaredField("name");
//对 name 进行暴破, 可以操作 private 属性
name.setAccessible(true);
//name.set(o, "老韩");
name.set(null, "老韩~");//因为 name 是 static 属性,因此 o 也可以写出 null
System.out.println(o);
System.out.println(name.get(o)); //获取属性值
System.out.println(name.get(null));//获取属性值, 要求 name 是 static
}
}
class Student {//类
public int age;
private static String name;
public Student() {//构造器
}
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
}
}