且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java反射获取实体的所有可见属性值,返回Object数组

更新时间:2022-09-05 11:44:58

获取实体的所有可见属性值

以下代码提供了两种实现,一种是基于List,一种是基于Map; 基于List的实现更节省内存,更高效一些;如果你有其它特殊的需求,可以根据实际参考以下代码进行扩展,或许有需要用到Map的情况呢!

当然,使用BeanUtils.describe或PropertyUtils.describe一两句代码就搞定了,但还需要额外添加包引用;另外效率方面是不是更高呢?我没有做过测试。

/**
   * 获取实体的所有可见属性值
   * @param object 实体类的实例
   * @return 返回一个Object数组,该数组包含实体的所有可见属性值
   */
  public Object[] getFieldValues(Object object) {
        if (object == null)
            return null;
        Field[] fields = object.getClass().getDeclaredFields();
        List<Object> fieldValueList = new ArrayList<Object>();
        //Map<String, Object> fieldValueMap = new HashMap<String, Object>();

        try {
            for (Field f : fields) {
                if (f.getModifiers() > 2) {
                    continue;
                }
                fieldValueList.add(f.get(object));
                //fieldValueMap.put(f.getName(), f.get(object));
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return fieldValueList.toArray();
        //return fieldValueMap.values().toArray();
    }

本例中使用getDeclaredFields,你可以参考与getFields区别,根据实际需求决定到底使用哪一个;

BeanUtils.describe实现本例的功能

BeanUtils.describe(object).values().toArray();

经过测试,该方法与本例代码返回的结果并不相同;

getFields()和getDeclaredFields()的区别

getFields()获得某个类的所有的公共(public)的字段,包括父类。

getDeclaredFields()获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段。

同样类似的还有getConstructors()和getDeclaredConstructors(),getMethods()和getDeclaredMethods()。

BeanUtils.describe与PropertyUtils.describe区别

这两个方法,基本上实现原理类似,内部代码很多都相同的,但在读取bean的某个属性的时候都是调用的某个类的getNestedProperty(bean, name)方法。

其实主要的区别就在这个方法中

PropertyUtils是调用的PropertyUtilsBean的这个方法,该方法读取属性值(调用getXxx方法)之后,value不做转化

而BeanUtils调用的是BeanUtilsBean的这个getNestedProperty方法,该方法在读取值之后,会再调用一次(getConvertUtils().convert(value));,进行类型转化成String。

因此BeanUtils.describe转化出来的Map的value都是String

BeanUtils.describe方法实现

  public Map describe(Object paramObject)
    throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
  {
    if (paramObject == null)
      return new HashMap();
    if (this.log.isDebugEnabled())
      this.log.debug("Describing bean: " + paramObject.getClass().getName());
    HashMap localHashMap = new HashMap();
    Object localObject;
    if (paramObject instanceof DynaBean)
    {
      localObject = ((DynaBean)paramObject).getDynaClass().getDynaProperties();
      for (int i = 0; i < localObject.length; ++i)
      {
        String str1 = localObject[i].getName();
        localHashMap.put(str1, getProperty(paramObject, str1));
      }
    }
    else
    {
      localObject = getPropertyUtils().getPropertyDescriptors(paramObject);
      Class localClass = paramObject.getClass();
      for (int j = 0; j < localObject.length; ++j)
      {
        String str2 = localObject[j].getName();
        if (getPropertyUtils().getReadMethod(localClass, localObject[j]) == null)
          continue;
        localHashMap.put(str2, getProperty(paramObject, str2));
      }
    }
    return (Map)localHashMap;
  }