Java中的反射机制

来源:互联网 发布:mac 如何恢复苹果系统 编辑:程序博客网 时间:2024/05/31 06:21

    之前也了解过java的反射机制,不过只是知道意思,而没有真正的去使用它,去进一步的他在什么时候去使用,这次在一个web项目中让我重新去认知了反射在我们程序中的重要性:

    1.使我们的代码更加灵活

    2.减少了我们代码之间的耦合性

    3.代码的复用性更强


反射的基础使用

-------------------------------------------------------------------------------------------

1、反射所需要的类模块

java.lang.Class(用来描述类信息的类)

java.lang.Constructor(提供构造方法信息和对构造方法的访问)

java.lang.reflect.Field(类的属性信息)

java.lang.reflect.Method(类的方法信息)

java.lang.reflect.Modifier(解析类和方法的访问权限)

2.反射机制获取Class的方式
    I、通过加载类的全称路径:Class class = Class.forName("类的路径");

    II、通过对象中的getClass方法得到:Class class = p.getClass();ps:p为某一个类的实例化对象

    III、通过类的class轻松拿到:Class class = 类名.class;

3.获取类属性

    I、获取所有属性

Filed[] fs = class.getDeclaredFileds();//获取所有属性(包含private、protected、public)

Filed[] fs = class.getFileds();//获取所有公有的属性

注解:Field下面的方法就不一一写了,大家多用就知道了

    II、获取指定属性

Field f = class.getDeclaredField("name");//通过属性名获取属性(包含private、protected、public)

Field f = class.getField("name");//获取公有的属性

   Ps:总之,就是加上Declared给他面子把所有的都可以让获取,不加Declared就没有那个权限了

4.获取类方法

    I、获取所有方法

Method[] ms = class.getDeclaredMethods();//同理

Method[] ms = class.getMethods();

    II、获取指定方法

Method m = class.getDeclaredMethod("setName",String.class);//通过方法名和方法参数获取

Method m = class.getMethod("getName",null);

Ps:java中的源码为:getDeclaredMethod(String name,Class<T>[] Parameter);这样大家应该就很清楚了

5.总结

    为什么用反射呢,那就是为了偷懒,在web项目中前台的参数如果很多,我们一个个获取并封装是不是有点太累了,我们对每一个对象都这么做的话,写个代码就要累死了,所有我就偷个懒自己写了个工具类,进行将参数转换为Bean的形式,现在我们开发中有好多的框架都帮我们做这些了,比如Struts2和SpringMvc等等,他们能够帮我们自动封装为对应对象的形式,不过偶尔自己写写会更好吧。。附上我自己写的http参数转换工具类,暂时还是菜鸟,有啥改进希望大家提出来

package com.wsq.crm.util;/** * Created by admin on 2017/7/27. */import com.sun.javafx.webkit.prism.PrismInvoker;import javax.servlet.http.HttpServletRequest;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.sql.Timestamp;import java.util.*;/** * 这是一个接受表单的参数,并将得到的参数封装为一个Bean对象 */public class RequestToBeanUtil {    /**     * turn方法的核心思想是找相同:req 和 tClass 一定用相同的部分,因为要将req中的参数值和cls的属性值进行自动设置     * @param req     * @param tClass     * @return     */    public static final Object turn(HttpServletRequest req,Class tClass) throws InvocationTargetException {        Object obj = null;        try {            obj = tClass.newInstance();            Enumeration<String> em = req.getParameterNames();            while (em.hasMoreElements()){                String key = em.nextElement();                String val = req.getParameter(key);                //查找class中对应的setXXX方法                Method[] methods = tClass.getDeclaredMethods();                for (Method m: methods){                    //忽略大小写                    if(m.getName().equalsIgnoreCase("set"+key)){                        Class pc[] = m.getParameterTypes();                        if(pc[0].getName().equalsIgnoreCase("float")){                            m.invoke(obj,Float.parseFloat(val));                            break;                        }else if (pc[0].getSimpleName().equalsIgnoreCase("int")){                            m.invoke(obj,Integer.parseInt(val));                            break;                        }else if (pc[0].getSimpleName().equalsIgnoreCase("boolean")){                            m.invoke(obj,Boolean.parseBoolean(val));                            break;                        }else if (pc[0].getSimpleName().equalsIgnoreCase("byte")){                            m.invoke(obj,Byte.parseByte(val));                            break;                        }else if (pc[0].getSimpleName().equalsIgnoreCase("timestamp")){                            m.invoke(obj, Timestamp.valueOf(val));                            break;                        }else{                            m.invoke(obj,val);                            break;                        }                    }                }            }        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        }        return obj;    }}