Java class 方法以 Class 和 Field 作为参数

Java class method with Class and Field as parameters

如何创建接受 Class 和 Field 作为参数的方法?像这样:

List<SomeClassEntity> list = ...;
// Service to make useful things around a list of objects
UsefulThingsService<SomeClassEntity> usefulThingsService = new UsefulThingsService<>();
// Maybe invoke like this. Did't work 
usefulThingsService.makeUsefulThings(list, SomeClassEntity.class, SomeClassEntity::getFieldOne);
// or like this. Will cause delayed runtime erros
usefulThingsService.makeUsefulThings(list, SomeClassEntity.class, "fieldTwo");



public class SomeClassEntity {

    Integer fieldOne = 10;
    Double fieldThree = 0.123;

    public Integer getFieldOne() {
        return fieldOne;
    }
    public void setFieldOne(Integer fieldOne) {
        this.fieldOne = fieldOne;
    }
    public Double getFieldThree() {
        return fieldThree;
    }
    public void setFieldThree(Double fieldThree) {
        this.fieldThree = fieldThree;
    }
}


public class UsefulThingsService<T> {
    public void makeUsefulThings(Class<T> someClassBClass, String fieldName) {
        // there is some code
    }
}

希望在编译阶段而不是在运行时获得正确的引用。

更新: 我需要看起来比这更方便的代码:

    Field fieldOne = null;
    try {
        fieldOne = SomeClassEntity.class.getDeclaredField("fieldOne");
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    }
    usefulThingsService.makeUsefulThings(SomeClassEntity.class, fieldOne);

我为下一次澄清道歉。
更新 2:
- 该服务将列表与之前的列表进行比较,仅显示对象(列表项)的更改字段并更新原始列表中对象中的这些字段。
- 目前我在实体的字段上使用注释,它实际上是实体的 ID,当我需要更新源列表中的实体字段时,该 ID 用于检测相同的实体(旧的和新的)。
- 服务检测带注释的字段并将其用于下一个更新过程。
- 我想拒绝使用注释并直接在服务的构造函数中提供一个字段。或者使用其他可以在 class 和编译阶段的字段之间建立关系的东西。

假设您想要字段访问,因为您想要获取 设置值,您需要两个函数:

public class UsefulThingsService<T> {
    public <V> void makeUsefulThings(List<T> list, Function<T,V> get, BiConsumer<T,V> set) {
        for(T object: list) {
            V v = get.apply(object);
            // there is some code
            set.accept(object, v);
        }
    }
}

usefulThingsService.makeUsefulThings(
    list, SomeClassEntity::getFieldOne, SomeClassEntity::setFieldOne);

usefulThingsService.makeUsefulThings(
    list, SomeClassEntity::getFieldThree, SomeClassEntity::setFieldThree);

但是,有些事情是开放的。例如,该服务应该如何对现场响应做一些有用的事情。 属性,甚至不知道它的实际类型。在您的示例中,两者都是 Number 的子类型,因此您可以声明 <V extends Number>,因此该方法知道如何提取数值,但是,构造适当的结果对象需要指定另一个函数参数。