java的反射机制--示例

来源:互联网 发布:域名服务器设置 编辑:程序博客网 时间:2024/06/07 02:34
**理解反射机制:**

1. JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2. Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
i. 获得类的Field实例
ii. 获得类的Constructor实例
iii. 获得类的Method实例
iv. 通过“字符串类名”动态创建类的实例,这种就是通过反射创建实例.

下面就通过最近学习的一个例子来模拟反射机制的运作方式,以后再框架里面的实例化都是通过反射实现的,框架为了方便管理,就需要自己通过反射来创建实例,而我们自己new出来的对象,对于框架来说,就不是自己生的”儿子”,不好管理。

例:
编写一个程序从控制台输入一个学生类的类名,如:com.bluebridge.reflect.Student,通过反射创建出学生对象;同时从控制台输入姓名,年龄,性别等信息。
a) 使用反射技术通过Field对象给属性赋值。
b) 使用反射技术调用“setter”的Method的invoke(student对象,值)方法来给学生对象的属性赋值

这里都是写在一个类里面的,包括main函数:

/**     * /* 能过类来获得该Class实例所表示的类的结构:     *  1. 属性,即字段 java.lang.reflect.Field      *  2. 构造函数java.lang.reflect.Constructor      *  3. 方法:java.lang.reflect.Method     *      * 总结,通过反射创建对象可以有以下两种方式: 1. Class.newInstance()通过默认构造函数创建对象 2.     * 通过类的Constructor构造器来对象,只要传入参数以构造器定义的参数列表一致。     *      *      * @param args     */    public static void main(String[] args) {        Scanner input = new Scanner(System.in);        // 输入需要创建的完整类名        System.out.print("请输入完整的类名(包名+类名):");        // 输入类名        String className = input.next();        try {            // 动态加载类,将字符串定的类加载到JVM中去运行,即在JVM环境下可以找到这样一个类            Class cls = Class.forName(className);            // 通过默认构造函数创建对象            Object object = cls.newInstance();            Field[] fields = cls.getDeclaredFields();            for (Field field : fields) {                String fileName = field.getName();                Field fild2 = cls.getDeclaredField(fileName);//得到申明的属性                fild2.setAccessible(true);//修改属性的可访问性,可以从private变成可以直接访问的                setValue(object, fild2, input);//调用setValue方法            }            System.out.println(object);            System.out.println("=============下面是调用方法===================");            //只得本类声明的方法            Method[] methods = cls.getDeclaredMethods();            Method setnameMethod = cls.getDeclaredMethod("setName",String.class);            setnameMethod.setAccessible(true);// 改变类的访问属性            System.out.print("请输入姓名:");            String string = input.next();            //调用setName方法            setnameMethod.invoke(object, string);            Method setAgeMethod = cls.getDeclaredMethod("setAge", Integer.TYPE);            setAgeMethod.setAccessible(true);            System.out.print("请输入年龄:");            int i = input.nextInt();            //调用setName方法            setAgeMethod.invoke(object, i);            Method setGenderMethod = cls.getDeclaredMethod("setGender",                    String.class);            setGenderMethod.setAccessible(true);            System.out.print("请输入性别:");            string = input.next();            setGenderMethod.invoke(object, string);            System.out.println(object);        } catch (ClassNotFoundException e) {            System.err.println(e.getMessage());        } catch (InstantiationException e) {            System.err.println(e.getMessage());        } catch (IllegalAccessException e) {            System.err.println(e.getMessage());        } catch (NoSuchFieldException e) {            System.err.println(e.getMessage());        } catch (SecurityException e) {            System.err.println(e.getMessage());        } catch (NoSuchMethodException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IllegalArgumentException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (InvocationTargetException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    /**     * 判断文件的参数的类型     *      * @param object     *            对象,Student     * @param fild2     * @param input     * @throws IllegalArgumentException     * @throws IllegalAccessException     */    public static void setValue(Object object, Field fild2, Scanner input)            throws IllegalArgumentException, IllegalAccessException {        Class fieldType = fild2.getType();        // int        if (fieldType == Integer.class || fieldType == Integer.TYPE) {            System.out.print("请输入" + fild2.getName() + ":");            int i = input.nextInt();            fild2.set(object, i);            // double        } else if (fieldType == Double.class || fieldType == Double.TYPE) {            System.out.print("请输入" + fild2.getName() + ":");            double dou = input.nextDouble();            fild2.set(object, dou);            // long        } else if (fieldType == Long.class || fieldType == Long.TYPE) {            System.out.print("请输入" + fild2.getName() + ":");            long log = input.nextLong();            fild2.set(object, log);            // string        } else if (fieldType == String.class) {            System.out.print("请输入" + fild2.getName() + ":");            String string = input.next();            fild2.set(object, string);            // char        } else if (fieldType == Character.TYPE || fieldType == Character.class) {            System.out.print("请输入" + fild2.getName() + ":");            char chrs = 0;            try {                chrs = (char) System.in.read();            } catch (IOException e) {                e.printStackTrace();            }            fild2.set(object, chrs);        }    }
0 0
原创粉丝点击