反射的基本创建

前言

        本篇为反射,反射技术,指的是加载类的字节码到内存,并以编程的方法解刨出类中的各个成分(成员变量、方法、构造器等)。


一、反射

        通过反射技术不知可以创建对象,还可以对对象的成员变量进行更改或者查看,由于构造器、成员变量、成员方法都有可能是私有的,使用普通创建或调用是无法对私有方法或变量进行获取,而反射可以。

1.获取字节码对象

        反射获取的是类下信息,即字节码对象,使用Class就可以获取到,由3种方法可以获取

        我们先定义一个Person类:

public class Person {
    private String name;
    private int age;
    private String gender;
    public Person(){
    }
    private Person(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    private void eat(String str){
        System.out.println(name+"和"+str+"一起吃饭.");
    }
}

        因为后面不使用get和set方法,所以省略了。

        首先可以通过类直接调用Class方法:

//第一种方法直接通过方法名调用class方法
Class<Person> pc = Person.class;

//第二种可以通过Class.forName()的方式进行获取,括号内需要填写全类名
Class<?> aClass = Class.forName("cn.reflex.demo1.Test1");

//第三种需要先创建对象,通过调用对象的getClass方法来获取
Person person=new Person();
Class<? extends Person> aClass1 = person.getClass();

        三种方法都可以获取类的字节码文件。

        获取得到字节码文件后就可以对类进行操作

二、获取构造器

        获取构造器可以使用getConstructor()来获取,括号内若不填写内容,就是无参构造器,若有参,则需要传入参数。如果构造器是私有的,则可以使用getDeclaredConstructor(),私有需要setAccessible(true);来进行暴力反射,代码如下:

//获取构造器
public class Test1 {
    public static void main(String[] args) throws Exception {
        //将文件转化为字节码对象
        Class<Person> pc = Person.class;
        //创建构造器,私有用getDeclaredConstructor,非私有用getConstructor
        Constructor<Person> personConstructor = pc.getDeclaredConstructor(String.class,int.class,String.class);
        //暴力反射
        personConstructor.setAccessible(true);
        //通过构造器创建实例对象
        Person person = personConstructor.newInstance("张三",18,"男");
        System.out.println(person);


    }
}

三、获取成员变量

        获取成员变量与构造器欸四,但获取成员变量关键字为getDeclaredField,因为成员变量一般都是私有状态,则一般使用getDeclaredField和setAccessible(true);进行暴力反射。

        代码如下:

//获取成员变量
public class Test2 {
    public static void main(String[] args) throws Exception {
        //创建对象
        Person person=new Person();
        //获取字节码文件
        Class<Person> pc = Person.class;
        //获取成员变量,因为成员变量一般为私有,可直接使用getDeclaredField方法提取
        Field personName = pc.getDeclaredField("name");
        Field personAge = pc.getDeclaredField("age");
        Field personGender = pc.getDeclaredField("gender");
        //私有成员变量需要setAccessible暴力反射.
        personName.setAccessible(true);
        personAge.setAccessible(true);
        personGender.setAccessible(true);
        //get可以获取数据,需要传入成员对象,set可以修改数据,需要传入成员对象和修改后的值
        personName.set(person,"张三");
        System.out.println(personName.get(person));

    }
}

四、获取成员方法

        获取方法的方式一样,方法名为getDeclaredMethod或getMethod,如果要获取的方法是私有的,则使用getDeclaredMethod,共有则用getMethod。

        代码如下:


public class Test3 {
    public static void main(String[] args) throws Exception {
        //创建对象
        Person person = new Person();
        //获取字节码队形
        Class<? extends Person> aClass = person.getClass();
        /*
        获取类的某个方法,私有可以使用getDeclaredMethod且需要setAccessible暴力反射
        公有的可直接使用getMethod
        需要传入方法名和参数类型列表
         */
        Method eat = aClass.getDeclaredMethod("eat", String.class);
        eat.setAccessible(true);
        //可通过invoke直接调用方法,需要传入调用的对象名,和参数列表.
        eat.invoke(person, "李四");
    }
}

        这样就可以对成员内的方法或变量进行操作。


总结

        本篇简单介绍了反射的基本创建和反射获取成员内的数据及方法。

  • 22
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值