反射
通过Java的反射机制,可以在程序中访问已经装载到JVM中的Java对象的描述,实现访问,检测和修改描述Java对象本身信息的功能。通过反射可以访问构造方法,成员变量,和成员方法。
访问构造方法:Java反射——访问构造方法
访问成员方法:Java反射——访问成员方法
访问成员变量
利用Field对象可以操作相应的成员变量。
Field类的常用方法:
方法 | 说明 |
---|---|
getName() | 获取成员变量的名称 |
getType() | 获得表示该成员变量类型的class对象 |
get(Object obj) | 获得指定对象obj中成员变量的值,返回值为Object型 |
set(Object obj, Object value) | 将指定对象obj中成员变量的值设为value |
getInt(Object obj) | 获得指定对象obj中类型为int的成员变量的值 |
setInt(Object obj, int i) | 将指定对象obj中类型为int的成员变量的值设置为i |
getFloat((Object obj)) | 获得指定对象obj中类型为float的成员变量的值 |
setFloat(Object obj, float f) | 将指定对象obj中类型为float的成员变量的值设置为f |
getBoolean(Object obj) | 获得指定对象obj中类型为Boolean的成员变量的值 |
setBoolean(Object obj, boolean z) | 将指定对象obj中类型为Boolean的成员变量的值设置为z |
setAccessible(boolean flag) | 此方法可以设置是否忽略权限限制直接访问private等私有权限的成员变量 |
getModifiers() | 获得可以解析出该成员变量所采用修饰符的整数 |
getModifiers()方法的返回值是所表示的修饰符信息,在该类中提供了一系列用来解析的静态方法,既可以查看是否被指定的修饰符修饰,还可以以字符串的形式获得所有修饰符。
Modifier类中的常用解析方法:
静态方法 | 说明 |
---|---|
isPublic(int mod) | 查看是否被public修饰符修饰,如果是返回true,反之返回false |
isProtected(int mod) | 查看是否被protected修饰符修饰,如果是返回true,反之返回false |
isPrivate(int mod) | 查看是否被private修饰符修饰,如果是返回true,反之返回false |
isStatic(int mod) | 查看是否被static修饰符修饰,如果是返回true,反之返回false |
isFinal(int mod) | 查看是否被Final修饰符修饰,如果是返回true,反之返回false |
toString(int mod) | 以字符串形式返回所有修饰符 |
获取和修改成员变量的值:
首先创建一个Study类,在该类中声明三个不同类型,不同修饰符的成员变量,并赋值。
public class Study {
public int id = 1;
public String name = "反射";
private double price = 3.1315;
}
然后在另一个类Study2中反射这三个变量。
public class Study2 {
public static void main(String[] args) {
try {
Class c = Class.forName("study.czm.Study");// 创建class对象
Field fi[] = c.getDeclaredFields();// 获取所有成员变量
for (Field f : fi) {
System.out.print(Modifier.toString(f.getModifiers()) + " ");// 获取成员变量修饰符
System.out.print(f.getType());// 获取成员变量类型
System.out.println();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
成功获取了成员变量的修饰符与类型
注意: String类型获得了完整的名称,需要将他简化,在获取成员变量类型的那一行代码加一个方法 getSimpleName() 即可。
System.out.print(f.getType().getSimpleName());// 获取成员变量类型
通过反射获取成员变量name的值
//创建对象
Constructor cs = c.getConstructor();
Study s = (Study) cs.newInstance();//获取Study对象
Field f1 = c.getDeclaredField("name");//指定获取name的成员变量属性
System.out.println("name的值:" + f1.get(s));//获取name成员变量的值
修改getDeclaredField()中的值可以获取不同变量的值,获取成员变量id的值:
//创建对象
Constructor cs = c.getConstructor();
Study s = (Study) cs.newInstance();//获取Study对象
Field f1 = c.getDeclaredField("id");//指定获取id的成员变量属性
System.out.println("id的值:" + f1.get(s));//获取id成员变量的值
double类型的修饰符是private私有的,所以需要获取权限
//创建对象
Constructor cs = c.getConstructor();
Study s = (Study) cs.newInstance();//获取Study对象
Field f1 = c.getDeclaredField("price");//指定获取price的成员变量属性
f1.setAccessible(true);//获取访问权限
System.out.println("price的值:" + f1.get(s));//获取price成员变量的值
除了获取我们还能修改这些值,以id为例
//创建对象
Constructor cs = c.getConstructor();
Study s = (Study) cs.newInstance();//获取Study对象
Field f1 = c.getDeclaredField("id");//指定获取id的成员变量属性
System.out.println("id本来的的值:" + f1.get(s));//获取id成员变量的值
f1.set(s, 100);//修改id的值
System.out.println("id修改后的值:" + f1.get(s));//输出id的值
Study2类完整代码:
public class Study2 {
public static void main(String[] args) {
try {
Class c = Class.forName("study.czm.Study");// 创建class对象
Field fi[] = c.getDeclaredFields();// 获取所有成员变量
for (Field f : fi) {
System.out.print(Modifier.toString(f.getModifiers()) + " ");// 获取成员变量修饰符
System.out.print(f.getType().getSimpleName() + " ");// 获取成员变量类型
System.out.print(f.getName());// 获取成员变量名称
System.out.println();
}
// 创建对象
Constructor cs1 = c.getConstructor();
Study s = (Study) cs1.newInstance();// 获取Study对象
Field f1 = c.getDeclaredField("id");// 指定获取id的成员变量属性
System.out.println("id本来的的值:" + f1.get(s));// 获取id成员变量的值
f1.set(s, 100);// 修改id的值
System.out.println("id修改后的值:" + f1.get(s));// 输出id的值
// 创建对象
Constructor cs2 = c.getConstructor();
s = (Study) cs2.newInstance();// 获取Study对象
Field f2 = c.getDeclaredField("name");// 指定获取name的成员变量属性
System.out.println("name的值:" + f2.get(s));// 获取name成员变量的值
// 创建对象
Constructor cs3 = c.getConstructor();
s = (Study) cs3.newInstance();// 获取Study对象
Field f3 = c.getDeclaredField("price");// 指定获取price的成员变量属性
f3.setAccessible(true);// 获取访问权限
System.out.println("price的值:" + f3.get(s));// 获取price成员变量的值
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
运行结果: