java - How can I find the target of a Java8 method reference? -


i want capture calls mock object

public interface service {     public string stringify(object o); } service = mockery.mock(service.class); mockery.allowing(service::stringify).with(42).will(() -> "42"); 

so inside allowing have function<object, string>

is there reflecto-magic let me find service function created method reference?

public withclause allowing(function<t,r> f) {     object myservicebackagain = findtargetof(function);     .... } 

i know function come these method references, i'm happy down-cast as necessary.

this not same question related is possible convert method reference methodhandle? because, start isn't same question, in related area. , if can methodhandle, can't target it.

using trick this post can find target. important method below findtarget. turns out, lambdas indeed capture targets, , can access them serializedlambda.

however, pretty nasty reflection hack , it's break in future versions. not condone usage.

import java.io.serializable; import java.lang.invoke.serializedlambda; import java.lang.reflect.invocationtargetexception; import java.lang.reflect.method; import java.util.optional; import java.util.function.function;  public class findmethodreferencetarget {   public static void main(string[] args) {     string s = "123";     optional<object> target = findtarget(s::charat);     system.out.println(target.get().equals(s));      object o = new findmethodreferencetarget();     target = findtarget(o::equals);     system.out.println(target.get().equals(o));   }    private static <t, r> optional<object> findtarget(       debuggablefunction<t, r> methodreference) {     return getlambda(methodreference).map(l -> l.getcapturedarg(0));   }    private static optional<serializedlambda> getlambda(serializable lambda) {     (class<?> cl = lambda.getclass(); cl != null; cl = cl.getsuperclass()) {       try {         method m = cl.getdeclaredmethod("writereplace");         m.setaccessible(true);         object replacement = m.invoke(lambda);         if (!(replacement instanceof serializedlambda)) {           break; // custom interface implementation         }         serializedlambda l = (serializedlambda) replacement;         return optional.of(l);       } catch (nosuchmethodexception e) {         // nothing       } catch (illegalaccessexception | invocationtargetexception e) {         break;       }     }      return optional.empty();   }    @functionalinterface   private static interface debuggablefunction<t, r> extends       serializable,       function<t, r> {} } 

Comments

Popular posts from this blog

Android : Making Listview full screen -

javascript - Parse JSON from the body of the POST -

javascript - Chrome Extension: Interacting with iframe embedded within popup -