一种在不使用反射的情况下获取字段值的方法

时间:2016-10-04 10:57:13

标签: java

我已经获得了一个包含大约200个字段的类,其中使用反射读取它们的值。看起来基本上就像这个

for (Field f : this.getClass().getFields())
        {
            try
            {
                Object o = f.get(this);

                if (f.getType() == String.class)
                {
                    //do things with the string
                }
            }
            catch (Exception ex)
            {
                logger.error("Cannot get value for field. {}", ex.getMessage());
            }

        }

这对于如此庞大的领域非常有效,因为我认为这是反思的重点。我被要求重构它,因为它很慢(是吗?)。

到目前为止,我唯一可以提出他的一个不合理的硬编码方法,还有另一种快速方法吗?

3 个答案:

答案 0 :(得分:4)

首先,您应该使用分析器验证它确实很慢。反射比正常访问变量慢,但这并不一定意味着它是缓慢的来源。

如果您使用setter修改这些值,只要调用setter,您就可以重构该类以更新ko.computed.fn。这样可以更快地访问字段而不是反射,但根据您的使用情况,可能无法访问这些字段。

答案 1 :(得分:3)

大部分时间用于获取Field对象(并可能过滤它们)实际的查找速度非常快。我使用ClassValue来缓存这些信息并加快速度。

public enum StringFields {
    INSTANCE;

    final ClassValue<List<Field>> fieldsCache = new ClassValue<List<Field>>() {
        @Override
        protected List<Field> computeValue(Class<?> type) {
            return Collections.unmodifiableList(
                    Stream.of(type.getFields())
                            .filter(f -> f.getType() == String.class)
                            .peek(f -> f.setAccessible(true)) // turn off security check
                            .collect(Collectors.toList()));
        }
    };

    public static List<Field> getAllStringFields(Class<?> type) {
        return INSTANCE.fieldsCache.get(type);
    }
}

答案 2 :(得分:1)

  

到目前为止,我唯一可以提出他的一个不合理的硬编码方法,还有另一种快速方法吗?

您可以使用反射来获取这些字段的getter并生成读取这些getter的代码。

然后,代码生成可以成为构建步骤的一部分。