(反射与类操作)反射调用成员

反射调用成员

对于成员信息的获取也是通过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方法的调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值