调用get/set方法

调用get/set方法

1.前提

在开发工作中遇到一个开发任务,将页面中的财务指标数据保存到数据库,具体机构如下图,并且表中字段有可能随着时间变化而变动。很显然这个时候创建表对象,并实现get/set方法取值/存值这种 硬编码的方式不能适用当前场景。用反射的方法实现,可以减少代码量,提高代码灵活性。
调用get/set方法_第1张图片

2.方法名拼接

TestModel.java

package Reflect;

public class TestModel {
    private String name;
    private int age;
    private String school;
    private boolean flag;
    
    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 String getSchool() {
        return school;
    }
    public void setSchool(String school) {
        this.school = school;
    }
    public boolean isFlag() {
        return isFlag;
    }
    public void setFlag(boolean flag) {
        isFlag = flag;
    }
  }

TestMain.java

package Reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class TestMain {

    public static void main(String[] arg){
	   TestModel testModel = new TestModel();
       try {
        	reflectProperty(testModel,"set");
            List data = (TestModel)reflectProperty(testModel,"get");
            for(String dataValue : data){
                System.out.println(dataValue);
            }
       } catch (Exception e) {
           e.printStackTrace();
       } 
    }
    public static Object reflectProperty(Object model,String methodType) throws Exception {
        Field[] field = model.getClass().getDeclaredFields();
        // 获取属性的名字
        String[] modelName = new String[field.length];
        String[] modelType = new String[field.length];
        List data = new ArrayList<>();
        List types = new ArrayList<>();
        for (int i = 0; i < field.length; i++) {
            // 获取属性的名字
            String name = field[i].getName();
            System.out.println("打印传入类型的属性列表:"+name);
            modelName[i] = name;
            // 获取属性类型
            String type = field[i].getGenericType().toString();
            modelType[i] = type;
            types.add(name);
            //关键。。。可访问私有变量
            field[i].setAccessible(true);
            if (type.equals("class java.lang.String")) {
                 // 如果type是类类型,则前面包含"class ",后面跟类名
                 name = upperCase(name);
                 if("get".equals(methodType)){
                     Method getMet = model.getClass().getMethod(methodType + name);
                     // 调用getter方法获取属性值
                    String value = (String) getMet.invoke(model);
                    if (value == null) {
                       value = "";
                    }
                   data.add(value);
                 }
                 if("set".equals(methodType)){
                    Method setMet =  model.getClass().getMethod(methodType+name,field[i].getType());
                    setMet.invoke(model, "test");
                 }
            }
         }
	   return data;
   }

    public static String upperCase(String str) {
        char[] ch = str.toCharArray();
        if (ch[0] >= 'a' && ch[0] <= 'z') {
            ch[0] = (char) (ch[0] - 32);
        }
        return new String(ch);
    }
 }

结果输出
调用get/set方法_第2张图片

方法总结:
虽然反射的性能不是很好,但是相比较于硬编码的不易扩展,getDeclareFields可以拿到所有的成员变量,后续添加或删除成员变量时,不用修改代码。
但是生成的get/set方法并不是只有已get/set开头的,而是以is开头的,比如boolean类型的成员变量。这个时候我们就需要去判断属性的类型,然后用不同的前缀来拼接get/set方法名,如下图给出的样例,ifFlag,就不能直接用get+fildName进行拼接
调用get/set方法_第3张图片
调用get/set方法_第4张图片

3.使用JDK工具类

Introspector和PropertyDescriptor 使用这两个工具类进行构造get、set方法。
调用get/set方法_第5张图片
输出:
调用get/set方法_第6张图片
方法总结:
相比用java反射获取的方法,使用工具类更加的通用,但是这两种方法都有一个通病,需要判断入参和返回的参数类型然后进行类型转换,这就要求你预判出所有可能的入参和返回值的类型,然后就行代码转化。

你可能感兴趣的:(java基础)