[~emmanuel], it's possible using some proxy magic. The idea is to create a proxy object for the type of interest and invoke the given method against it (inspired by this [blog post|http://benjiweber.co.uk/blog/2013/12/28/typesafe-database-interaction-with-java-8/]). This allows to obtain the method and thus property name (and type) in the invocation handler.
The following example uses plain dynamic proxies and hence is limited to interfaces, but of course it could be done similarly for classes using Javassist etc:
{code} public class MethodReferenceTest {
@Test public void testMethodReference() throws Exception { // prints "Passed property is: getBar" assertEquals( new PropertyReferencer<>( Foo.class ).printProperty( Foo::getBar ) , "getBar" ) ; }
private interface Foo { public String getBar(); }
private static class PropertyReferencer<T> {
private final T proxy;
@SuppressWarnings("unchecked") public PropertyReferencer(Class<T> type) { InvocationHandler handler = new MethodNameRetrievalHandler(); proxy = (T) Proxy.newProxyInstance( type.getClassLoader(), new Class<?>[] { type }, handler ); }
private void printProperty getProperty (Function<T, ?> s) { String methodName = return (String) s.apply( proxy ); System.out.println( "Passed property is: " + methodName ); } }
private static class MethodNameRetrievalHandler implements InvocationHandler {
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.getName(); } } } {code}
|