fork(1) download
  1. import java.lang.invoke.CallSite;
  2. import java.lang.invoke.LambdaMetafactory;
  3. import java.lang.invoke.MethodHandle;
  4. import java.lang.invoke.MethodHandles;
  5. import java.lang.invoke.MethodType;
  6.  
  7. class Ideone {
  8.  
  9. public static void main(String[] args) throws Throwable {
  10. ISetter<TestEntity, Long> setter = getSetter(TestEntity.class, "id", Long.class);
  11.  
  12. TestEntity te = new TestEntity(10L);
  13. System.out.println(te.getId());
  14. setter.set(te, 15L);
  15. System.out.println(te.getId());
  16. }
  17.  
  18. public static <T, R> ISetter<T, R> getSetter(Class<T> clazz, String fieldName, Class<R> fieldType) throws Throwable {
  19.  
  20. MethodHandles.Lookup caller = MethodHandles.lookup();
  21. MethodType setter = MethodType.methodType(void.class, fieldType);
  22. MethodHandle target = caller.findVirtual(clazz, computeSetterName(fieldName), setter);
  23. MethodType func = target.type();
  24.  
  25. CallSite site = LambdaMetafactory.metafactory(
  26. caller,
  27. "set",
  28. MethodType.methodType(ISetter.class),
  29. func.erase(),
  30. target,
  31. func
  32. );
  33.  
  34. MethodHandle factory = site.getTarget();
  35. ISetter<T, R> r = (ISetter<T, R>) factory.invoke();
  36.  
  37. return r;
  38. }
  39.  
  40. public static String computeSetterName(String name) {
  41. return "set" + Character.toUpperCase(name.charAt(0)) + name.substring(1);
  42. }
  43.  
  44. }
  45.  
  46. interface ISetter<T, R> {
  47. void set(T object, R value);
  48. }
  49.  
  50. class TestEntity {
  51.  
  52. private Long id;
  53.  
  54.  
  55. public TestEntity(Long id) {
  56. this.id = id;
  57. }
  58.  
  59.  
  60. public Long getId() {
  61. return id;
  62. }
  63.  
  64. public void setId(Long id) {
  65. this.id = id;
  66. }
  67. }
Success #stdin #stdout 0.12s 4386816KB
stdin
Standard input is empty
stdout
10
15