staticClassforName(String packageAndClassName);
静态成员方法,通过 Class 直接调用,所需参数是对应类完整的包名.类名,通过包名.类名获取对应类 Class 对象。
ClassgetClass();Object类内方法,任何一个对象都可以通过 getClass() 方法获取对应类型的 Class 对象
类名.class
属性获取,获取当前类对应的 Class 对象
packagecom.qfedu.a_reflect;/*
* 获取 Class 对象相关操作
*/publicclassGetClassObject{publicstaticvoidmain(String[] args)throwsClassNotFoundException{/*
* Class.forName()
*
* 动态!!!只要用户提供完整的包名.类名,我可以获取到任意 Class 对象
* 【工厂模式】
*/Class<?> cls1 =Class.forName("com.qfedu.a_reflect.Person");/*
* 通过实例化 Person 对象,利用 getClass() 方法获取 Class 对象
*
* 用于类型判断,已知实例化对象情况下,获取对应类型。
*/Class<?extendsPerson> cls2 =newPerson().getClass();/*
* 通过 类名获取 Class 对象属性
*
* 常用于类型约束,类型表示,方法参数类型约束,成员变量数据类型描述,返回值类型数据类型描述
*/Class<Person> cls3 =Person.class;System.out.println(cls1);System.out.println(cls2);System.out.println(cls3);/*
* 以上三种方式获取的 Class 对象是不是同一个对象???
* 不管通过那种方式获取 Class 对象都是同一个 Class 对象,因为 com.qfedu.a_reflect.Person
* 类型在整个代码中有且只有一个。
*/System.out.println(cls1 == cls2);System.out.println(cls2 == cls3);System.out.println(cls3 == cls1);}}
3. 通过Class 对象获取对应类 Constructor 对象
3.1 Constructor 构造方法关注的内容
格式:
权限修饰符 类名(形式参数列表) {
方法体;
}
public Person() {}
public Person(String name) {this.name = name}
对应当前 Person 类而言,选择利用不同的构造方法 + new 关键字实例化对象,你认为具有唯一性的数据是哪一个???
调用:
Person p1 = new Person();
Person p2 = new Person("张三");
如果可以得到 Class 对象,证明已经明确当前对应类型是哪一个类,需要获取构造方法,有且只有构造方法形式参数列表不同。可以通过不同的形式参数列表,获取对应的构造方法 Constructor 对象。
3.2 获取 Constructor 对象相关操作方法
Constructor[]getConstructors();
通过 Class 对象调用,获取对应类型所有非私有化构造方法 Constructor 类对象数组
Constructor[]getDeclaredConstructors();
【暴力反射】
通过 Class 对象调用,获取对应类型所有构造方法 Constructor 类对象数组,包括私有化构造方法
ConstructorgetConstructor(Class... parameterTypes);
通过 Class 对象调用,获取指定参数类型的非私有化构造方法。
Class... parameterTypes 不定长参数 Class 类型,使用 Class 类型来约束构造方法参数类型。
案例:Class<Person> cls =Person.class;// 获取 Person 无参数构造方法Constructor c1 = cls.getConstructor();==>publicPerson();// 获取 Person 类型 int, String 参数构造方法Constructor c1 = cls.getConstructor(int.class,String.class);==>publicPerson(int,String);ConstructorgetDeclaredConstructor(Class... parameterTypes);
【暴力反射】
通过 Class 对象调用,获取指定参数类型的构造方法。包括私有化构造方法
Class... parameterTypes 不定长参数 Class 类型,使用 Class 类型来约束构造方法参数类型。
案例:
Class<Person> cls =Person.class;// 获取 Person 私有化 String 类型构造方法Constructor c1 = cls.getDeclaredConstructor(String.class);==>privatePerson(String)
Field[]getFields();
获取类内所有非私有化成员变量 Field 对象数组。
Field[]getDeclaredFields();
【暴力反射】
获取类内所有成员变量 Field 对象数组。包括私有化成员变量
FieldgetField(String fieldName);
根据指定的成员变量名称,获取非私有化成员变量 Field 对象
FieldgetDeclaredField(String fieldName);
【暴力反射】
根据指定的成员变量名称,获取成员变量 Field 对象,包括私有化成员变量
5.3 操作 Field 对象赋值取值成员变量
void set(Objec obj, Object value);
通过 Field 对象调用,第一个参数 是需要设置对应成员变量的类对象 第二个参数 是赋值给当前成员变量的数据
Object get(Object obj);
通过 Field 对象调用,得到对应成员变量数据,参数是从哪一个类对象中,获取对应成员变量数据
5.4 代码演示
packagecom.qfedu.a_reflect;importjava.lang.reflect.Field;importjava.lang.reflect.InvocationTargetException;/*
* Field 成员变量类对象
*/publicclassGetFieldObject{publicstaticvoidmain(String[] args)throwsClassNotFoundException,NoSuchFieldException,SecurityException,InstantiationException,IllegalAccessException,IllegalArgumentException,InvocationTargetException,NoSuchMethodException{/*
* Class.forName()
*
* 动态!!!只要用户提供完整的包名.类名,我可以获取到任意 Class 对象 【工厂模式】
*/Class<?> cls1 =Class.forName("com.qfedu.a_reflect.Person");/*
* Field[] getFields();
* 获取类内所有非私有化成员变量 Field 对象数组。
*/Field[] fields = cls1.getFields();for(Field field : fields){System.out.println(field);}System.out.println();/*
* Field[] getDeclaredFields();
* 【暴力反射】
* 获取类内所有成员变量 Field 对象数组。包括私有化成员变量
*/Field[] declaredFields = cls1.getDeclaredFields();for(Field field : declaredFields){System.out.println(field);}System.out.println();/*
* Field getField(String fieldName);
* 根据指定的成员变量名称,获取非私有化成员变量 Field 对象
*/Field test = cls1.getField("test");System.out.println(test);System.out.println();/*
* Field getDeclaredField(String fieldName);
* 【暴力反射】 根据指定的成员变量名称,获取成员变量 Field
* 对象,包括私有化成员变量
*/Field id = cls1.getDeclaredField("id");Field name = cls1.getDeclaredField("name");System.out.println(id);System.out.println(name);System.out.println();Object obj = cls1.getConstructor().newInstance();System.out.println(obj);/*
* 赋值成员变量数据
*/
test.set(obj,100);System.out.println(obj);
id.setAccessible(true);
name.setAccessible(true);
id.set(obj,1);
name.set(obj,"张三");System.out.println(obj);/*
* 取值操作
*/System.out.println();System.out.println(test.get(obj));System.out.println(id.get(obj));System.out.println(name.get(obj));}}