Как создать прокси несвязанного универсального типа с ByteBuddy? - PullRequest
1 голос
/ 22 сентября 2019

В качестве упражнения мне нужно извлечь имя метода из ссылки на метод.Например:

interface Marker {}

interface Foo extends Marker {

    String foo();
}

class MethodNameExtractor {

    static <T extends Marker> String extract(Function<T, String> methodReference) throws Exception {
        var proxy = (T) new ByteBuddy()
            .subclass(Marker.class)
            .method(not(isDeclaredBy(Object.class)).and(returns(String.class)))
            .intercept(InvocationHandlerAdapter.of(MethodNameExtractor::invoke))
            .make()
            .load(MethodNameExtractor.class.getClassLoader()).getLoaded().getConstructor()
            .newInstance();
        return methodReference.apply(proxy);
    }

    static Object invoke(Object proxy, Method method, Object[] args) {
        return method.getName();
    }
}


class MethodNameExtractorTest {

    @Test
    public void itExtractsTheMethodName() {
        assertEquals("foo", extract(Foo::foo));
    }
}

Но тест выдает:

java.lang.ClassCastException: class Marker$ByteBuddy$EHoz8bj6 cannot be cast to class Foo (Marker$ByteBuddy$EHoz8bj6 is in unnamed module of loader net.bytebuddy.dynamic.loading.ByteArrayClassLoader @4009e306; Foo is in unnamed module of loader 'app')
    at MethodNameExtractor.extract(MethodNameExtractor.java:3)
    at MethodNameExtractorTest.itExtractsTheMethodName(MethodNameExtractorTest.java:5)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:532)
    ...

То есть я не могу привести прокси к T?Как создать прокси, который можно передать в качестве аргумента ссылки на метод?

1 Ответ

0 голосов
/ 23 сентября 2019

Вы реализуете Marker, но ожидаете, что созданный экземпляр будет иметь тип Foo, который является подтипом Marker.Byte Buddy уже сохраняет безопасность типов, поэтому небезопасное приведение маскирует эту проблему.Вместо этого внедрите Foo, и ваша проблема должна быть решена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...