java - 通过 Java 反射重新创建(通用)成员并填充/分配字段成员

标签 java generics reflection

我有一组包含任意数量的非自定义成员的类——只是原语、包装器等;其中一些可以用 @Encrypted 注释,以便进行不同的处理。所有类型都实现了 Envelope

我正在创建两个 Map(基于给定类型),存储“字段名称”(作为键)和“字段值”(作为值)。

问题是当我尝试根据 Map 重新创建类型时。这是我目前所拥有的:

import io.shido.domain.Envelope;
import org.apache.commons.lang3.reflect.FieldUtils;

import java.util.Map;

public final class Factory<T extends Envelope> {
  private final Map<String, Object> regularMembers;

  private final Map<String, Object> secureMembers;

  public Factory(final Map<String, Object> regularMembers, final Map<String, Object> secureMembers) {
    this.regularMembers = regularMembers;
    this.secureMembers = secureMembers;
  }

  public T build() {
    try {
      final ParameterizedType superClass = (ParameterizedType) getClass().getGenericSuperclass(); // This doesn't work >:(
      final Class<T> type = (Class<T>) superClass.getActualTypeArguments()[0];
      final T result = type.newInstance();
      regularMembers.forEach((fieldName, fieldValue) -> assign(result, fieldName, fieldValue));
      secureMembers.forEach((fieldName, fieldValue) -> assign(result, fieldName, fieldValue));
      return result;
    } catch (final Exception e) {
      logger.error("Cannot build type based on input parameters due to:", e);
      throw new IllegalStateException(e.toString());
    }
  }

  private void assign(final T type, final String fieldName, final Object fieldValue) {
    try {
      FieldUtils.getField(type.getClass(), fieldName).set(type, fieldValue);
    } catch (final IllegalAccessException e) {
      e.printStackTrace();
    }
  }
}

任何线索如何处理这个?我可以使用任何库。


我唯一的限制是当前类型没有 setter — 我无法添加它们,而且我使用的是 Java 8

例如,这是一个例子:

public final class ExampleType implements Envelope {
  @Encrypted
  private String first;

  private String second;

  @Encrypted
  private String third;

  public ExampleType() { }

  public ExampleType(final String first, final String second, final String third) {
    this.first = first;
    this.second = second;
    this.third = third;
  }

  public String getFirst() { return first; }

  public String getSecond() { return second; }

  public String getThird() { return third; }
}

最佳答案

要扩展我的评论,请尝试这样的事情(未经测试):

import io.shido.domain.Envelope;
import org.apache.commons.lang3.reflect.FieldUtils;

import java.util.Map;

public final class Factory<T extends Envelope> {
  private final Class<T> clazz;

  private final Map<String, Object> regularMembers;

  private final Map<String, Object> secureMembers;

  public Factory(final Class<T> clazz, final Map<String, Object> regularMembers, final Map<String, Object> secureMembers) {
    this.clazz = clazz;
    this.regularMembers = regularMembers;
    this.secureMembers = secureMembers;
  }

  public T build() {
    try {
      final T result = clazz.newInstance();
      regularMembers.forEach((fieldName, fieldValue) -> assign(result, fieldName, fieldValue));
      secureMembers.forEach((fieldName, fieldValue) -> assign(result, fieldName, fieldValue));
      return result;
    } catch (final Exception e) {
      logger.error("Cannot build type based on input parameters due to:", e);
      throw new IllegalStateException(e.toString());
    }
  }

  private void assign(final T type, final String fieldName, final Object fieldValue) {
    try {
      FieldUtils.getField(type.getClass(), fieldName).set(type, fieldValue);
    } catch (final IllegalAccessException e) {
      e.printStackTrace();
    }
  }
}

关于java - 通过 Java 反射重新创建(通用)成员并填充/分配字段成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53786465/

相关文章:

java - 用于 pre-1.5 假枚举的 EnumSet?

java - 如何编写java程序来启动远程机器上的程序?

java - 在 Eclipse 项目之外以编程方式运行 JUnit 测试

generics - 通用超特征/需要一揽子 impl

Java:创建作为函数参数传递的泛型类型的实例

c# - 从反射 ParamInfo[] 创建匿名类型

java - 如何将 XML 文件展平为一组 xpath 表达式?

java - 为什么可能 arrayList 只显示一个字符串?

swift - 返回类型为 Self 而不是 Array 的 CollectionType 扩展

C#、反射和原始类型