一、反射获取成员字段
<1>Filed类:代表了类中的一个成员变量:
1、得到一个类中的所有成员变量:
(1)所有公共成员(public)变量:getFields();
(2)所有声明过(任意权限)的成员变量:getDeclaredFields();
(3)获取指定的public的成员变量:getField(Stringname)
(4)获取指定的任意权限的成员变量:getDeclaredField(Stringname)
获取成员变量的实体类对象:
public class Student {
public String name;
private int age;
int height;
protected String sex;
}
【1】 Class类的getFields()方法
Class clazz = Class.forName("com.jtt.demo.Student");
Field[] fields = clazz.getFields();
for (Field f : fields) {
System.out.println(f);
}
输出结果:public java.lang.String com.jtt.demo.Student.name
只获取公共的成员变量
【2】getDeclaredFields()方法
Class clazz = Class.forName("com.jtt.demo.Student");
Field[] fields = clazz.getDeclaredFields();
for (Field f : fields) {
System.out.println(f);
}
输出结果:
public java.lang.Stringcom.jtt.demo.Student.name
private intcom.jtt.demo.Student.age
int com.jtt.demo.Student.height
protected java.lang.Stringcom.jtt.demo.Student.sex
输出了所有申明的成员变量
<2>调用Field类对象的set/get方法来操作对应的字段
其中需要注意的是操作不同权限的成员变量,尤其是private
其中:
Class clazz = Class.forName("com.jtt.demo.Student");
Field field = clazz.getField("age");// age不是public
Object obj = clazz.newInstance();// 实例化
field.set(obj, 25);
System.out.println(field.get(obj));
输出结果:java.lang.NoSuchFieldException: age
原因:age为private类型字段,而getField只能获取public类型字段,故没有获取到这个字段,
这时候我们自然而然的会想起用getDeclaredField()方法
但是还是会报错,不过跟之前的不同
输出结果:java.lang.IllegalAccessException:
Class com.jtt.jdk5.ClassDemo can not access amember of class com.jtt.demo.Student with modifiers "private"
原因:因为age为private类型字段,不能直接操作
解决方法:使用getDeclaredField( )+ 取消对反射对象进行访问权限检查机制操作非public字段
Class clazz = Class.forName("com.jtt.demo.Student");
Field field = clazz.getDeclaredField("age");// age不是public,用getDeclaredField可获取
// 取消对反射对象进行访问权限检查机制
field.setAccessible(true);
Object obj = clazz.newInstance();// 实例化
field.set(obj, 25);
System.out.println(field.get(obj));
输出结果: 25
跟获取成员变量方法类似
<1> Method类:代表了类中的一个成员方法:
1、得到一个类中的所有成员方法:
(1)所有公共成员(public)方法:getMethods();
(2)所有声明过(任意权限)的成员方法:getDeclaredMethods();
(3)获取指定的public的成员方法:
getMethod(Stringname,Class<?>…parameterTypes)
(4)获取指定的任意权限的成员方法:
getDeclaredMethod(String name,Class<?>…)
获取成员方法的实体类对象:public class Student {
private int age;
private String name;
public void method() {
System.out.println("method run...");
}
private void method2() {
System.out.println("method2 run...");
}
public void paramMethod(String name, int age) {
System.out.println(name + "paramMethod run..." + age);
}
【1】
Class类
的
getMethods()
方法
Class clazz = Class.forName("com.jtt.demo.Student");
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
输出结果:
public void com.jtt.demo.Student.paramMethod(java.lang.String,int)
public void com.jtt.demo.Student.method()
public final native java.lang.Class java.lang.Object.getClass()
public native int java.lang.Object.hashCode()
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
只获取公共的成员方法,【注意】也包含父类的public方法
【2】getDeclaredFields()方法
Class clazz = Class.forName("com.jtt.demo.Student");
Field[] fields = clazz.getDeclaredFields();
for (Field f : fields) {
System.out.println(f);
}
输出结果:
private void com.jtt.demo.Student.method2()
public void com.jtt.demo.Student.paramMethod(java.lang.String,int)
public void com.jtt.demo.Student.method()
输出了所有申明的成员方法;【注意】不包含父类的方法,仅仅包含子类任意访问权限的方法
<2>调用Method类对象的invoke方法来调用指定的方法
其中需要注意的是操作不同权限的成员方法
[1]. 操作公有public字段类对象
(1)反射调用无参方法
Class clazz = Class.forName("com.jtt.demo.Student");
Object obj = clazz.newInstance();
Method method = clazz.getMethod("method", null);
method.invoke(obj, null);
(2)反射调用有参方法
Class clazz = Class.forName("com.jtt.demo.Student");
Object obj = clazz.newInstance();
Method method = clazz.getMethod("paramMethod", String.class, int.class);
method.invoke(obj, "lisi", 25);
[2]. 操作非公有public字段类对象
其中:
Class clazz = Class.forName("com.jtt.demo.Student");
Object obj = clazz.newInstance();
Method method = clazz.getMethod("method2",null);
method.invoke(obj, null);
输出结果:
java.lang.NoSuchMethodException: com.jtt.demo.Student.Method2()
原因:Method2()为private类型方法,而getMethod只能获取public类型字段,故没有获取到这个方法,
这时候我们自然而然的会想起用getDeclaredMethod()方法
Class clazz = Class.forName("com.jtt.demo.Student");
Object obj = clazz.newInstance();
Method method = clazz.getDeclaredMethod("method2", null);
method.invoke(obj, null);
但是还是会报错,不过跟之前的不同
输出结果: java.lang.IllegalAccessException:
Class com.jtt.jdk5.ClassDemo can not access a member of class com.jtt.demo.Student with modifiers "private"
原因:因为method2为private类型方法,不能直接操作
解决方法:使用getDeclaredMethod( )+ 取消对反射对象进行访问权限检查机制 操作非public方法
Class clazz = Class.forName("com.jtt.demo.Student");
Object obj = clazz.newInstance();
Method method = clazz.getDeclaredMethod("method2", null);
// 指示JVM取消对访问权限的检查
method.setAccessible(true);
method.invoke(obj, null);
输出结果: method2 run...