0x01 前言
前面一章节的学习,学习到类如何获取类还有获取类的方法与调用类方法。
通过本章节即可学习到如何修改成员变量与调用类的构造方法。
0x01.1 目录结构
# 目录结构
├── 反射
│ └── java获取成员变量与构造函数信息4
│ ├── Test.java (用来做测试的方法)
│ ├── Person.java
0x01.2 例子-Person类(用于理解的)
// 该类具体路径: 反射.java获取成员变量与构造函数信息4.Person
package 反射.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的性别: 女