Java中反射机制简介

“反射”听这个名字有点高级的样子,它实际的作用是什么呢,就是可以在程序运行时去加载某个类,或去调用某个类里面的方法(这是我的理解)
先上代码,有个初步认识:

//这是最简单的Bean
public class User {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
//反射,最常用的大概就是这些。
public class ReflectTest {

    public static void main(String[] args){

        try {
            /*获取class的几种方法*/
            Class c1 = Class.forName("com.smc.test.User");
            Class c2 = User.class;
            User user3 = new User();
            Class c3 = user3.getClass();
            System.out.println(c1.getName());
            System.out.println(c2.getName());
            System.out.println(c3.getName());

            /*遍历class里面的所有方法*/
            Field[] fs = c1.getDeclaredFields();
            StringBuffer sb = new StringBuffer();
            for(Field field : fs){
                sb.append(Modifier.toString(field.getModifiers())+"  ");
                sb.append(field.getType().getName() + " " );
                sb.append(field.getName() + ";\n");
            }
            System.out.println(sb.toString());

            /*根据name来获取class里面的某个field*/
            Field fieldName = c1.getDeclaredField("name");
            Object user = c1.newInstance();
            fieldName.setAccessible(true);
            fieldName.set(user, "xiaoming");
            System.out.println(((User)user).getName());

            /*根据name来获取class里面的某个method*/
            Method methodSetName = c1.getDeclaredMethod("setName", String.class);
            Method methodGetName = c1.getDeclaredMethod("getName", null);
            methodSetName.invoke(user, "honghong");
            String name = (String) methodGetName.invoke(user, null);
            System.out.println("name = " + name);



        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}

反射获取Class

反射的操作,基本都是基于java.lang.Class类来进行的,那么如何来获取Class对象呢。一般来说,就这三种方法。

//第一种,调用Class的静态方法(forName)来获取,传入需要反射类的完整路径。
Class c1 = Class.forName("com.smc.test.User");
//第二种,直接使用目标类.class来获取
Class c2 = User.class;
//第三种,调用目标类实例的getClass()方法,(这里我不明白,都获取到实例了,为什么还要反射呢。)
User user3 = new User();
Class c3 = user3.getClass();

使用反射来获取里面的某个Field

Field应该知道的吧,就是类里面的参数,变量,属性。

//通过之前获取到的Class实例,调用getDeclaredField()方法,传入需要反射Field的名称,这里是“name”,这样就获取对应的Field了。
Field fieldName = c1.getDeclaredField("name");
//然后给Class,实例一个目标类出来,毕竟要操作里面的属性了。
Object user = c1.newInstance();
//先要调用Field的setAccessible(true)方法,这样就可以给里面的私有属性赋值了。
fieldName.setAccessible(true);
//最后一步,调用Field方法的set()方法,传入目标类实例对象,和需要设置属性的值。最后看一下属性有没有被设置进去。
fieldName.set(user, "xiaoming");
System.out.println(((User)user).getName());

使用反射来调用方法

//这里通过Class实例调用getDeclaredMethod()传入method的名字和参数(这里必须要传正确,因为有方法重载的可能性),就得到了Method实例。
Method methodSetName = c1.getDeclaredMethod("setName", String.class);
//没有参数就传null
Method methodGetName = c1.getDeclaredMethod("getName", null);
//然后调用invoke()方法,将操作对象和变量值传入,方法就调用成功了,
methodSetName.invoke(user, "honghong");
String name = (String) methodGetName.invoke(user, null);
//最后再试一下,成功了没有
System.out.println("name = " + name);

灵活使用反射,会使开发变得更加灵活,但是不要依赖反射,毕竟反射不是主流开发,效率上来讲,没有直接使用高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值