java中的反射

前言:

反射可以得到类或对象的所有属性与方法!比较官方一点的说法就是:JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

运用领域:

写框架需要运用到反射,有的业务也需要到反射(比如通过实体类生成sql,前提是表明必须按照特定的规则)。反射在重构代码中能起到很大的作用,也能减少相应的代码。缺点是反射多了会影响效率,但可以说是微乎其微了。

反射简单案例
1反射封装的方法,比较常见的有通过field设置 value与根据field取value的值。
	/**
     * @param fieldName 属性名
     * @param obj 被取值对象
     * @retrun 取到的值
     * */
    private Object getFieldValueByFieldName(String fieldName, Object obj) {
        try {
            Field field = obj.getClass().getDeclaredField(fieldName);
            //设置对象的访问权限,保证对private的属性的访问
            field.setAccessible(true);
            return  field.get(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 	/**
     * @param fieldName 属性名
     * @param obj 需要设置属性值的对象
     * @param value 内容
     * */
    private void setFieldValueByFieldName(String fieldName, Object obj,Object value) {
        try {
            Class c = obj.getClass();
            Field f = c.getDeclaredField(fieldName);
            f.setAccessible(true);
            f.set(object,value);
        } catch (Exception  e) {
            e.printStackTrace();
        }
    }

2.通过方法名运行带参方法
    /**
     * @param methodName 方法名
     * @param obj 方法所在对象
     * @param args  方法所需参数
     * */
    private static Object invokeMethod(String methodName, Object obj, Object... args) {
        Object returnObj = null;
        try {
            Class<?>[] clazz = new Class[args.length];//定义一个类数组,因为方法参数可以是各种类型
            for(int i=0;i<args.length;i++){
                clazz[i] =  args[i].getClass();//将参数匹配为相应的类型
            }
            Method method= obj.getClass().getMethod(methodName,clazz);//类型在这里使用
            returnObj = method.invoke(obj, args);//参数在这里,Object万物皆对象
        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnObj;
    }
3.通过反射实体类生成sql语句,建表规则要遵循特定的规则才行。
/**
 * 反射生成SQL语句的工具类
 * 表名与字段的命名规则必须是下划线命名法
 */
public class ReflectSqlUtil {

    private static BaseConditionalField conditionalField = new BaseConditionalField();
    /**
     * 生成插入语句
     * @param tablename 表明
     * @param clazz 与数据库中字段一一对应的类
     * @param t 有数据的实体
     * @param <T> 数据实体类型 如 User
     */
    public static  <T> String getInsertSql(String tablename, Class<T> clazz, T t){
        //insert into table_name (column_name1,column_name2, ...) values (value1,value2, ...)
        String sql = "";
        Field[] fields = ReflectUtil.getFieldsDirectly(clazz, false);
        StringBuffer topHalf = new StringBuffer("insert into "+tablename+" (");
        StringBuffer afterAalf = new StringBuffer("values (");
        for (Field field : fields) {
            if ("ID".equals(field.getName()) || "id".equals(field.getName())){
                continue;   //id 自动生成无需手动插入
            }
            topHalf.append(humpToUnderline(field.getName()) + ",");
            if (ReflectUtil.getFieldValue(t, field.getName()) instanceof String) {
                afterAalf.append( ReflectUtil.getFieldValue(t, field.getName())==null?"'0',":"'" +ReflectUtil.getFieldValue(t, field.getName()) + "',");
            } else {
                afterAalf.append(ReflectUtil.getFieldValue(t, field.getName())==null?"0,":ReflectUtil.getFieldValue(t, field.getName()) + ",");
            }
        }
        topHalf = new StringBuffer(StrUtil.removeSuffix(topHalf.toString(), ","));
        afterAalf = new StringBuffer(StrUtil.removeSuffix(afterAalf.toString(), ","));
        topHalf.append(") ");
        afterAalf.append(") ");
        sql = topHalf.toString() + afterAalf.toString();
        return sql;
    }

    /**
     * 生成更新语句
     * 必须含有id
     * 数据实体中 null 与 空字段不参与更新
     * @param tablename 数据库中的表明
     * @param clazz 与数据库中字段一一对应的类
     * @param t 有数据的实体
     * @param <T> 数据实体类型,如 User
     */
    public static  <T> String getUpdateSql(String tablename, Class<T> clazz, T t){
        //UPDATE table_name SET column_name1 = value1, column_name2 = value2, ... where ID=xxx
        //or
        //UPDATE table_name SET column_name1 = value1, column_name2 = value2, ... where id=xxx
        String sql = "";
//        String id = ""; //保存id名:ID or id
        Field[] fields = ReflectUtil.getFieldsDirectly(clazz, false);
        sql = "update "+tablename+" set ";
        for (Field field : fields) {
            StringBuffer tmp = new StringBuffer();
            if ("ID".equals(field.getName()) || "id".equals(field.getName())){
//                id = field.getName();
                continue;//更新的时候无需set id=xxx
            }
            if (ReflectUtil.getFieldValue(t, field.getName()) != null && ReflectUtil.getFieldValue(t, field.getName()) != "") {
                tmp.append(humpToUnderline(field.getName()) + "=");
                if (ReflectUtil.getFieldValue(t, field.getName()) instanceof String) {
                    tmp.append( "'" + ReflectUtil.getFieldValue(t, field.getName()) + "',");
                } else {
                    tmp.append(ReflectUtil.getFieldValue(t, field.getName()) + ",");
                }
                sql += tmp;
            }
        }
        //sql = StrUtil.removeSuffix(sql, ",") + " where " + id + "='" + ReflectUtil.getFieldValue(t, id)+"'";
        //去除条件在xml中拼接
        sql = StrUtil.removeSuffix(sql, ",");
        return sql;
    }

    /***
     * 驼峰命名转为下划线命名
     * @param para 驼峰命名的字符串
     */

    public static String humpToUnderline(String para){
        StringBuilder sb=new StringBuilder(para);
        int temp=0;//定位
        if (!para.contains("_")) {
            for(int i=0;i<para.length();i++){
                if(Character.isUpperCase(para.charAt(i))){
                    sb.insert(i+temp, "_");
                    temp+=1;
                }
            }
        }
        return sb.toString().toUpperCase();
    }

    /**
     * 获取条件语句sql
     * @param tableBean 对象
     * @param excludes 需要排除的条件
     * @return
     */
    public static String getConditionalSql(Object tableBean, List<String> excludes) {
        StringBuffer conditionalSql = new StringBuffer();
        JSONObject beanJson = JSONObject.parseObject(JSONObject.toJSONString(tableBean));
        Class cls = conditionalField.getClass();
        Field[] fields = cls.getDeclaredFields();
        for(int i=0; i<fields.length; i++){
            Field f = fields[i];
            f.setAccessible(true);
            if (beanJson.containsKey(f.getName())){
                if (excludes != null && excludes.contains(f.getName())){
                    continue;
                }
                conditionalSql.append(" and ");
                conditionalSql.append(humpToUnderline(f.getName()));
                conditionalSql.append("=");
                conditionalSql.append("'");
                conditionalSql.append(beanJson.get(f.getName()));
                conditionalSql.append("'");
            }
        }
        return conditionalSql.toString();
    }

    /**
     * 获取查询SQL
     * @param tableName
     * @return
     */
    public static String getQuerySql(String tableName) {
        StringBuffer querySql = new StringBuffer();
        querySql.append("select * from ");
        querySql.append(tableName);
        querySql.append(" ");
        return querySql.toString();
    }
}

目前对反射的理解,后续会继续更新ing…

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值