回顾:Class 对象:在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
Class对象获取的三种法法:
//方法一:Class class对象名 = 类名.class
Class cls1 = String.class;
//方法二:Class class对象名 = 对象.getClass()
String s = "chengyuan";
Class cls2 = s.getClass();
//方法三:Class class对象名 = Class.forName("类名");
Class cls3 = Class.forName("java.lang.String");
本文重点:
1 通过Class实例来获取Field对象:
public Field[] getFields() :返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
public Field[] getDeclaredFields() :返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段。
Field getField(String name) :返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
public Field[] getDeclaredFields() :返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段。
2 Field对象包含一个field的所有的信息
String getName() :获取成员变量的变量名
Class<?> getType() :获取成员变量的数据类型
int getModifiers() :获取当前成员的修饰符
3 通过Field对象调用 setAccessible(boolean flag)方法,实现对成员变量的修饰符更改,例如把private修饰的成员变量,改成public修饰,从而实现反射调用,但是并非所有的成员变量都可以修改,若是该成员变量定义了securityManager规则则会阻止修改
代码演示:
class RefletionField {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Student stu1 = new Student(20170516,"程远",21);
Class cls = stu1.getClass();
Field fieldNum = cls.getField("num");//得到这个字段对象
System.out.println(fieldNum.getName());
System.out.println(fieldNum.getType());
System.out.println(fieldNum.getModifiers());
//通过成员变量的反射对象调用get(对象) 来得到对象的对应字段的值
System.out.println(fieldNum.get(stu1));
System.out.println("===============");
//通过成员变量的反射对象调用set(对象,值) 来得到对象的对应字段的值
fieldNum.set(stu1,123);
System.out.println(fieldNum.get(stu1));
System.out.println("===============");
System.out.println("通过反射手段强制性破坏封装性:修改权限修饰符为public");
fieldNum.setAccessible(true);
System.out.println(fieldNum.getModifiers());
}
}
class Student{
public int num;
private String name ;
private int age;
public Student(int num, String name, int age) {
this.num = num;
this.name = name;
this.age = age;
}
}