0x01 前言
前面一章节的学习,学习到类如何获取类还有获取类的方法与调用类方法。
通过本章节即可学习到如何修改成员变量与调用类的构造方法。
0x01.1 目录结构
# 目录结构├── 反射│ └── java获取成员变量与构造函数信息4│ ├── Test.java (用来做测试的方法)│ ├── Person.java
0x01.2 例子-Person类(用于理解的)
// 该类具体路径: 反射.java获取成员变量与构造函数信息4.Personpackage 反射.java获取成员变量与构造函数信息4;public class Person {public String name = "大狗";public int age;private String sex;private static final int height = 160;// 构造方法一public Person() {this.setName("二狗");this.setAge(18);this.setSex("男");System.out.println(" ");System.out.println("====================");System.out.println("公共的无参数构造方法被调用");}// 构造方法二public Person(String name) {this.setName(name);System.out.println(" ");System.out.println("====================");System.out.println("公共的带name参数的构造方法被调用");System.out.println("TA的名字: " + name);}// 构造方法三public Person(String name,int age) {this.setName(name);this.setAge(age);System.out.println(" ");System.out.println("====================");System.out.println("公共的带name参数与age参数的构造方法被调用");System.out.println("TA的名字: " + name);System.out.println("TA的年龄: " + age);}// 构造方法四private Person(String name, String sex) {this.setName(name);this.setSex(sex);System.out.println(" ");System.out.println("====================");System.out.println("私有的带name参数与sex参数的构造方法被调用");System.out.println("TA的名字: " + name);System.out.println("TA的性别: " + sex);}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}private void setSex(String sex) {this.sex = sex;}}
0x02 获取当前类所有成员变量的信息
0x02.1 getFields()
getFields() //获取的是所有的public的成员变量的信息,包括父类继承而来的
// 例子1-获取Person类所有的public的成员变量的信息import java.lang.reflect.Field;public class Test {public static void main(String[] args) {try {Class p = Class.forName("反射.java获取成员变量与构造函数信息4.Person");// 通过类类型,创建该类对象Object pObject = p.newInstance();System.out.println(" ");System.out.println("====================================");Field[] fs = p.getFields();for (Field field : fs) {System.out.println(" ");System.out.println("成员变量的名称是: " + field.getName());System.out.println("成员变量的类型是: " + field.getType().getName());}System.out.println("====================================");System.out.println(" ");} catch (Exception e) {e.printStackTrace();}}}// 运行结果====================公共的无参数构造方法被调用====================================成员变量的名称是: name成员变量的类型是: java.lang.String成员变量的名称是: age成员变量的类型是: int====================================
0x02.2 getDeclaredFields()
getDeclaredFields() 获取的是该类自己声明的成员变量的信息
// 例子2-获取Person类自己声明的成员变量的信息package 反射.java获取成员变量与构造函数信息4;import java.lang.reflect.Field;public class Test {public static void main(String[] args) {try {Class p = Class.forName("反射.java获取成员变量与构造函数信息4.Person");// 通过类类型,创建该类对象Object pObject = p.newInstance();// 例子1:System.out.println(" ");System.out.println("====================================");Field[] fs = p.getDeclaredFields();for (Field field : fs) {System.out.println(" ");System.out.println("成员变量的名称是: " + field.getName());System.out.println("成员变量的类型是: " + field.getType().getName());}System.out.println("====================================");System.out.println(" ");} catch (Exception e) {e.printStackTrace();}}}// 运行结果====================公共的无参数构造方法被调用====================================成员变量的名称是: name成员变量的类型是: java.lang.String成员变量的名称是: age成员变量的类型是: int成员变量的名称是: sex成员变量的类型是: java.lang.String成员变量的名称是: height成员变量的类型是: int====================================
0x03 获取当前类某个成员变量的信息
0x03.1 getField()
getField() 获取的是当前类某个public的成员变量的信息,包括父类继承而来的
// 例子1-获取公共name成员变量的值package 反射.java获取成员变量与构造函数信息4;import java.lang.reflect.Field;public class Test {public static void main(String[] args) {try {Class p = Class.forName("反射.java获取成员变量与构造函数信息4.Person");// 通过类类型,创建该类对象Object pObject = p.newInstance();// 获取公共name成员变量的信息Field nameField = p.getField("name");// 获取公共name成员变量的值System.out.println("");System.out.println(nameField.get(pObject));} catch (Exception e) {e.printStackTrace();}}}// 运行结果====================公共的无参数构造方法被调用二狗
0x03.2 getDeclaredField()
getDeclaredField() 获取的是当前类自己声明的某个成员变量的信息,不问访问权限
// 例子2-修改与获取私有age成员变量的值package 反射.java获取成员变量与构造函数信息4;import java.lang.reflect.Field;public class Test {public static void main(String[] args) {try {Class p = Class.forName("反射.java获取成员变量与构造函数信息4.Person");// 通过类类型,创建该类对象Object pObject = p.newInstance();// 获取私有age成员变量的信息Field ageField = p.getDeclaredField("age");// 忽略访问修饰符的检查,这样就可以调用私有方法或是成员变量ageField.setAccessible(true);// 修改私有age成员变量的值ageField.set(pObject, 22);// 获取私有age成员变量的值System.out.println(" ");System.out.println(ageField.get(pObject));} catch (Exception e) {e.printStackTrace();}}}// 运行结果====================公共的无参数构造方法被调用22
// 例子3-修改私有的 static final关键字修饰的height成员变量package 反射.java获取成员变量与构造函数信息4;import java.lang.reflect.Field;import java.lang.reflect.Modifier;public class Test {public static void main(String[] args) {try {Class p = Class.forName("反射.java获取成员变量与构造函数信息4.Person");// 通过类类型,创建该类对象Object pObject = p.newInstance();// 当我们要修改static final关键字修饰的成员变量的时候// 我们需要修改Field中的modifiers数据域,清除代表final的那个bit// 这样才可以正常修改Field heightField = p.getDeclaredField("height");heightField.setAccessible(true);Field ms = heightField.getClass().getDeclaredField("modifiers");// 忽略访问修饰符的检查,这样就可以调用私有方法或是成员变量ms.setAccessible(true);ms.setInt(heightField, heightField.getModifiers() & ~Modifier.FINAL);// 修改私有的final关键字修饰的height成员变量的值heightField.set(pObject, 180);// 获取 static final关键字修饰的height成员变量的值System.out.println("");System.out.println(heightField.get(pObject));} catch (Exception e) {e.printStackTrace();}}}// 运行结果====================公共的无参数构造方法被调用180
0x04 获取当前类所有构造函数
0x04.1 getConstructors()
getConstructors() 获取的是所有的public访问权限的构造函数
// 例子-获取Person类所有的public访问权限的构造函数package 反射.java获取成员变量与构造函数信息4;import java.lang.reflect.Constructor;public class Test {public static void main(String[] args) {try {Class p = Class.forName("反射.java获取成员变量与构造函数信息4.Person");System.out.println(" ");System.out.println("====================================");Constructor[] pcs = p.getConstructors();for (Constructor constructor : pcs) {System.out.print(constructor.getName()+"(");//获取构造函数的参数列表--->得到的是参数列表的类类型Class[] paramTypes = constructor.getParameterTypes();for (Class class1 : paramTypes) {System.out.print(class1.getName()+",");}System.out.println(")");}System.out.println("====================================");System.out.println(" ");} catch (Exception e) {e.printStackTrace();}}}// 运行结果====================================反射.java获取成员变量与构造函数信息4.Person(java.lang.String,int,)反射.java获取成员变量与构造函数信息4.Person(java.lang.String,)反射.java获取成员变量与构造函数信息4.Person()====================================
0x04.2 getDeclaredConstructors()
getDeclaredConstructors() 获取的是该类自己声明的所有构造函数
// 获取Person类自己声明的所有构造函数package 反射.java获取成员变量与构造函数信息4;import java.lang.reflect.Constructor;public class Test {public static void main(String[] args) {try {Class p = Class.forName("反射.java获取成员变量与构造函数信息4.Person");System.out.println(" ");System.out.println("====================================");Constructor[] pcs = p.getDeclaredConstructors();for (Constructor constructor : pcs) {System.out.print(constructor.getName()+"(");//获取构造函数的参数列表--->得到的是参数列表的类类型Class[] paramTypes = constructor.getParameterTypes();for (Class class1 : paramTypes) {System.out.print(class1.getName()+",");}System.out.println(")");}System.out.println("====================================");System.out.println(" ");} catch (Exception e) {e.printStackTrace();}}}// 运行结果====================================反射.java获取成员变量与构造函数信息4.Person(java.lang.String,java.lang.String,)反射.java获取成员变量与构造函数信息4.Person(java.lang.String,int,)反射.java获取成员变量与构造函数信息4.Person(java.lang.String,)反射.java获取成员变量与构造函数信息4.Person()====================================
0x05 获取当前类某个构造函数
0x05.1 注意
调用的是那个构造方法与自己传入 getConstructor() / getDeclaredConstructor() 的参数有关例如-想调用的是公共构造方法 getConstructor()Person()类的构造方法一 那么直接传入 p.getConstructor()Person()类的构造方法二 那么直接传入 p.getConstructor(String.class)Person()类的构造方法三 那么直接传入 p.getConstructor(String.class, int.class)例如-想调用的是私有构造方法 getDeclaredConstructor()Person()类的构造方法四 那么直接传入Constructor test = p.getDeclaredConstructor(String.class, String.class);test.setAccessible(true);
0x05.2 getConstructor()
getConstructor() 获取的是当前类某个public访问权限的构造函数,包括父类继承而来的
// 例子1: Person类-获取无参数的公共构造方法// 也就是获取 构造方法一package 反射.java获取成员变量与构造函数信息4;import java.lang.reflect.Constructor;public class Test {public static void main(String[] args) {try {Class p = Class.forName("反射.java获取成员变量与构造函数信息4.Person");System.out.println(" ");System.out.println("====================================");Constructor test = p.getConstructor();System.out.print(test.getName()+"(");//获取构造函数的参数列表--->得到的是参数列表的类类型Class[] paramTypes = test.getParameterTypes();for (Class class1 : paramTypes) {System.out.print(class1.getName()+",");}System.out.println(")");//通过构造器对象 newInstance 方法对对象进行初始化 有参数构造函数Object obj=test.newInstance();} catch (Exception e) {e.printStackTrace();}}}// 运行结果====================================反射.java获取成员变量与构造函数信息4.Person()====================公共的无参数构造方法被调用
// 例子2: Person类-获取有两个参数的公共构造方法// 也就是获取 构造方法三package 反射.java获取成员变量与构造函数信息4;import java.lang.reflect.Constructor;public class Test {public static void main(String[] args) {try {Class p = Class.forName("反射.java获取成员变量与构造函数信息4.Person");System.out.println(" ");System.out.println("====================================");Constructor test = p.getConstructor(String.class, int.class);System.out.print(test.getName()+"(");//获取构造函数的参数列表--->得到的是参数列表的类类型Class[] paramTypes = test.getParameterTypes();for (Class class1 : paramTypes) {System.out.print(class1.getName()+",");}System.out.println(")");//通过构造器对象 newInstance 方法对对象进行初始化 有参数构造函数Object obj=test.newInstance("神奇的我",12);} catch (Exception e) {e.printStackTrace();}}}// 运行结果====================================反射.java获取成员变量与构造函数信息4.Person(java.lang.String,int,)====================公共的带name参数与age参数的构造方法被调用TA的名字: 神奇的我TA的年龄: 12
0x05.3 getDeclaredConstructor()
getDeclaredConstructor() 获取的是当前类自己声明的某个构造函数,不问访问权限
// 例子3: Person类-获取有两个参数的私有构造方法// 也就是获取 构造方法四package 反射.java获取成员变量与构造函数信息4;import java.lang.reflect.Constructor;public class Test {public static void main(String[] args) {try {Class p = Class.forName("反射.java获取成员变量与构造函数信息4.Person");System.out.println(" ");System.out.println("====================================");Constructor test = p.getDeclaredConstructor(String.class, String.class);test.setAccessible(true);System.out.print(test.getName()+"(");//获取构造函数的参数列表--->得到的是参数列表的类类型Class[] paramTypes = test.getParameterTypes();for (Class class1 : paramTypes) {System.out.print(class1.getName()+",");}System.out.println(")");//通过构造器对象 newInstance 方法对对象进行初始化 有参数构造函数Object obj=test.newInstance("哇哦","女");} catch (Exception e) {e.printStackTrace();}}}// 运行结果====================================反射.java获取成员变量与构造函数信息4.Person(java.lang.String,java.lang.String,)====================私有的带name参数与sex参数的构造方法被调用TA的名字: 哇哦TA的性别: 女
