Consider a field weight
in class Animal
. I want to be able to create a getter and setter functional interface objects for manipulating this field.
class Animal {
int weight;
}
My current approach is similar to one used for methods:
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();
}
But this gives the following error:
java.lang.invoke.LambdaConversionException: Unsupported MethodHandle kind: getField x.Animal.weight:()int
UPDATE
I am trying to create a class ObjectMap
implementing interface Map
, which basically tries to represent an object as a Map
, where the object can be of any type. Was currently using Field.get()
and Field.set()
for manipulating fields in get()
and put()
methods, and using above mentioned approach to create Supplier
and Consumer
objects for invoking getter and setter methods. I was wondering if i could merge the two separate methods into one.
Example class which could be used as a Map
through 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;
}
}
And here is the expected usage:
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