当前位置: 首页 > 知识库问答 >
问题:

如何为字段创建功能接口实现?

薛坚
2023-03-14
class Animal {
  int weight;
}
public static Supplier getter(Object obj, Class<?> cls, Field f) throws Exception {
  boolean isstatic = Modifier.isStatic(f.getModifiers());
  MethodType sSig = MethodType.methodType(f.getType());
  Class<?> dCls = Supplier.class;
  MethodType dSig = MethodType.methodType(Object.class);
  String dMthd = "get";
  MethodType dType = isstatic? MethodType.methodType(dCls) : MethodType.methodType(dCls, cls);
  MethodHandles.Lookup lookup = MethodHandles.lookup();
  MethodHandle fctry = LambdaMetafactory.metafactory(lookup, dMthd, dType, dSig, lookup.unreflectGetter(f), sSig).getTarget();
  fctry = !isstatic && obj!=null? fctry.bindTo(obj) : fctry;
  return (Supplier)fctry.invoke();
}

但这会产生以下错误:

java.lang.invoke.LambdaConversionException: Unsupported MethodHandle kind: getField x.Animal.weight:()int

更新

我试图创建一个类objectmap,实现interface map,它基本上试图将对象表示为map,其中对象可以是任何类型。当前正在使用field.get()field.set()操作get()put()方法中的字段,并使用上述方法创建supplierconsumer对象以调用getter和setter方法。我想知道是否可以将这两个单独的方法合并为一个。

可用作映射对象映射示例类:

public class ThisCanBeAnything {
  /* fields */
  public String normalField;
  private int hiddenFiled;
  private String hiddenReadonlyField;

  /* getters and setters */
  public int hiddenField() {
    return hiddenField;
  }
  public void hiddenField(int v) {
    System.out.println("set: hiddenField="+v);
    hiddenField = v;
  }

  public String hiddenReadonlyField() {
    return hiddenReadonlyField;
  }
}

下面是预期的用法:

Object o = new ThisCanBeAnything();
Map m = new ObjectMap(o);
m.put("normalField", "Normal");
System.out.println(m.get("normalField")); // Normal
m.put("hiddenField", 1); // set: hiddenField=1
System.out.println(m.get("hiddenField")); // 1
m.put("hiddenReadonlyField", 1); // does not do anything
System.out.println(m.get("hiddenReadonlyField")); // null

共有1个答案

鱼宜
2023-03-14

您可以直接编写lambda,根本不需要lambdametafactory:

public static Supplier getter(Object obj, Field f) {
    return () -> {
        try {
            return f.get(obj);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    };
}

或运行时类型安全版本:

public static <T> Supplier<T> getter(Object obj, Class<T> fieldClass, Field f) {

    if (!fieldClass.isAssignableFrom(f.getType()))
        throw new RuntimeException("Field is not of expected type");

    return () -> {
        try {
            return (T) f.get(obj);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    };
}

例如:

private class X {
    public int a;
}

@Test
public void supplier_getter_test() throws NoSuchFieldException {
    X a = new X();
    a.a = 5;

    Supplier<Integer> sup = getter(a, int.class, X.class.getField("a"));

    assertEquals(5, sup.get().intValue());
}
 类似资料:
  • 问题内容: 例如,如果我们具有以下接口: 以下结构: 并实现了接口: 然后在我们的主要功能中,如果我们想测试一下,将无法正常工作: 这确实按预期工作: 我想念什么?:-) 问题答案: 的接收者是一个值,因此您正在更改结构的副本。 更改为

  • 把大象装进冰箱分几步?三步:把冰箱门打开,把大象装进去,关门,搞定~ 新建接口分几步?也是三步: 获取权限 找到一个项目 新建接口 搞定~ 获取权限 新用户登录拥有 个人空间 分组下的全部权限,个人空间分组仅自己可见,因此可以在这里任意试用 YApi 的功能。 除此以外没有任何项目或分组的权限,只能浏览已存在分组下面的公开项目。 如果找不到想找的项目,可能是尚未成为项目成员,此时应联系 项目组长

  • 我试图创建像@repository这样的系统。

  • 泛型可译: 可翻译的: 我需要获取的实例,但我不能: 那么,如何创建实例并填充ths接口的teh相关属性呢?因为我需要在测试方法中给出这个实例作为返回值:

  • 用户Spring批处理查找实体表。问题是关于ItemWriter,或者,可能是关于ItemProc的。 对于这个实体,一切都很好。我可以从源代码中读取实体,并将其保存到用户_导出表中 我有一个: 2)比,我在我的实体用户添加字段。这个字段是列表,我需要将这个字段保存在其他表Device_Export中。 我有两个表格用户导出和设备导出。设备导出具有用户导出的外键,并且关系是多个设备与一个用户的关系

  • 原始关闭原因未解决 我只找到了有关实时数据库而不是fiRecovery的答案,我希望能够让用户搜索名称并取回所有匹配的文档。我正在使用一个文本字段来调用文本字段文本的函数onChange(也限制为每2秒调用一次以减少调用量)。 这就是同一集合中每个文档的建模方式。我只想获取字段“name”与文本字段搜索文本匹配的文档。到目前为止,我已经尝试过: 我可以让代码工作的唯一方法是使用Anywhere F