Java中反射机制简介

来源:互联网 发布:excel数据区域设置 编辑:程序博客网 时间:2024/06/07 18:32

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

//这是最简单的Beanpublic 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);//没有参数就传nullMethod methodGetName = c1.getDeclaredMethod("getName", null);//然后调用invoke()方法,将操作对象和变量值传入,方法就调用成功了,methodSetName.invoke(user, "honghong");String name = (String) methodGetName.invoke(user, null);//最后再试一下,成功了没有System.out.println("name = " + name);

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

0 0
原创粉丝点击