С Java 8 вы можете сделать это с помощью нескольких строк кода (почти) без каких-либо дополнительных библиотек. Ключ должен преобразовать ваш метод в сериализуемое лямбда-выражение. Следовательно, вы можете просто определить простой интерфейс, например:
@FunctionalInterface
public interface SerializableFunction<I, O> extends Function<I, O>, Serializable {
// Combined interface for Function and Serializable
}
Теперь нам нужно преобразовать наше лямбда-выражение в SerializedLambda
объект. По-видимому, Oracle на самом деле не хочет, чтобы мы это делали, поэтому возьмите это с крошкой соли ... Поскольку требуемый метод является закрытым, мы должны вызвать его с помощью отражений:
private static final <T> String nameOf(SerializableFunction<T, ?> lambda) {
Method findMethod = ReflectionUtils.findMethod(lambda.getClass(), "writeReplace");
findMethod.setAccessible(true);
SerializedLambda invokeMethod = (SerializedLambda) ReflectionUtils.invokeMethod(findMethod, lambda);
return invokeMethod.getImplMethodName();
}
Я использую класс Springs ReflectionUtils
здесь для простоты, но вы, конечно, можете заменить его, вручную перебирая все суперклассы и используя getDeclaredMethod
, чтобы найти метод writeReplace
.
И это уже, теперь вы можете использовать это так:
@Test
public void testNameOf() throws Throwable {
assertEquals("getName", nameOf(MyClassTest::getName));
}
Я не проверял это с модульной системой Java 9s, так что в качестве небольшой оговорки было бы сложнее сделать это с более свежими версиями Java ...