gpt4 book ai didi

java - 如何为字段创建功能接口(interface)实现?

转载 作者:搜寻专家 更新时间:2023-11-01 01:25:19 26 4
gpt4 key购买 nike

考虑 Animal 类中的字段 weight。我希望能够创建一个 gettersetter 功能接口(interface)对象来操作这个字段。

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

更新

我正在尝试创建一个实现 interface Map 的类 ObjectMap,它基本上试图表示一个对象作为 Map,其中 object 可以是任何类型。当前正在使用 Field.get()Field.set()get()put()< 中操作字段 方法,并使用上述方法创建 SupplierConsumer 对象以调用 gettersetter 方法.我想知道是否可以将这两种独立的方法合并为一个。

可以通过 ObjectMap 用作 Map 的示例类:

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

最佳答案

你把它变得太困难了。当你有一个Field时,你可以直接调用unreflectGetter在查找工厂上检索 MethodHandle:

Produces a method handle giving read access to a reflected field. The type of the method handle will have a return type of the field's value type. If the field is static, the method handle will take no arguments. Otherwise, its single argument will be the instance containing the field.

public static Supplier<Object> getter(Object obj, Class<?> cls, Field f) {
f.setAccessible(true);
MethodHandles.Lookup lookup = MethodHandles.lookup();
return () -> {
try {
MethodHandle handle = lookup.unreflectGetter(f);
return Modifier.isStatic(f.getModifiers()) ? handle.invoke() : handle.invoke(obj);
} catch (Throwable t) {
throw new IllegalArgumentException(t);
}
};
}

这将返回字段值的供应商。根据字段的可访问性,您可能需要调用 setAccessible(true) .

请注意,方法句柄和反射 API 也不同 in terms of performance并且可能会更快。

关于java - 如何为字段创建功能接口(interface)实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36694744/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com