Как я могу создать реализацию функционального интерфейса для полей?
Рассмотрим полеweight
в классеAnimal
, Я хочу быть в состоянии создатьдобытчик а такжесеттер функциональный интерфейс объектов для манипулирования этим полем.
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()
методы и использование вышеупомянутого подхода для созданияSupplier
а такжеConsumer
объекты для вызовадобытчик а такжесеттер методы. Мне было интересно, смогу ли я объединить два отдельных метода в один.
Пример класса, который можно использовать какMap
черезObjectMap
:
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