反射调用成员
对于成员信息的获取也是通过Class获取的:
返回
Field数组,
Field对象反映由此类
对象表示的类或接口声明的所有字段:public Field[] getDeclareds() throws SecurityException返回 Field对象,该对象反映此
类
对象表示的类或接口的指定声明字段:public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException返回一个包含 Field对象的数组, Field对象反映此
类
对象所表示的类或接口的所有可访问公共字段:public Field[] getFields() throws SecurityException返回 Field对象,该对象反映此 类对象表示的类或接口的指定公共成员字段:public FieldgetField(String name) throws NoSuchFieldException, SecurityException
范例:获取类中的成员
Person
package reflect;
public class Person extends AbstractBase implements IChannelService{
private String name = "张三";
protected int age = 10;
public Person(){ //无参构造
System.out.println("Person类的无参构造方法");
}
}
IChannelService接口
package reflect;
public interface IChannelService {
public static final String NAME = "IChannelService";
}
AbstractBase抽象类
package reflect;
public abstract class AbstractBase {
protected static final String BASE = "AbstractBase";
}
测试类
package reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Demo{
public static void main(String[] args) throws Exception{
Class<?> cls =Class.forName("reflect.Person"); //获取指定类的Class对象
System.out.println("------------获取全部成员------------");
Field[] fields = cls.getDeclaredFields();
for(Field field: fields){
System.out.println(field);
}
System.out.println("------------获取可访问公共成员------------");
Field[] fields1 =cls.getFields();
for(Field field: fields1){
System.out.println(field);
}
}
}
------------获取全部成员------------
private java.lang.String reflect.Person.name
protected int reflect.Person.age
------------获取可访问公共成员------------
public static final java.lang.String reflect.IChannelService.NAME
在Field类里面最为重要的操作形式并不是获取全部的成员,而是如下三个方法;
- 设置属性内容:public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException
- 获取属性内容: public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException
- 解除封装:public void setAccessible(boolean flag)
所有的成员是在对象实例化之后进行空间分配的,所以此时一定要先有实例化对象之后才可以进行成员属性操作。
范例:直接调用Person类中name私有属性
package reflect;
import java.io.FilenameFilter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Demo{
public static void main(String[] args) throws Exception{
Class<?> cls =Class.forName("reflect.Person"); //获取指定类的Class对象
Object obj =cls.getDeclaredConstructor().newInstance(); //用无参构造实例化一个对象(分配成员空间)
Field fieldName = cls.getDeclaredField("name"); //获取成员对象
fieldName.setAccessible(true); //解除封装(无视访问控制)
fieldName.set(obj,"李四"); //设置属性内容,等价于Person对象.name = "李四";
System.out.println(fieldName.get(obj)); //获取属性内容
}
}
Person类的无参构造方法
李四
通过一系列的分析可以发现,类之中的构造、方法、成员属性都可以通过反射实现调用,但是对于成员的调用反射很少这样直接处理,大部分操作都应该由setter完成或getter处理。对于Field类在实际开发之中只有一个方法最为常用:
- 获取成员类型:public Class<?> getType()
范例:获取Person类的name成员类型
package reflect;
import java.io.FilenameFilter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Demo{
public static void main(String[] args) throws Exception{
Class<?> cls =Class.forName("reflect.Person"); //获取指定类的Class对象
Field fieldName = cls.getDeclaredField("name"); //获取成员对象
System.out.println(fieldName.getType().getSimpleName()); //获取简单类名称
}
}
String
在以后的开发中进行反射处理的时候,往往会利用Field与Method实现类中的setter方法的调用。