我使用ByteBuddy在运行时实现标记接口和任意数量的类似访问器的无参数值方法,由标记注释标识,如:
interface Foo {
// marker interface
}
// this is the kind of thing we're generating implementations of
interface MyFoo extends Foo {
@Value
SomeClass bar();
}
我有一个实现委托的功能接口,如:
interface Implementation<F extends Foo, V> {
@RuntimeType
V apply(@This F foo);
}
和生产实际实现的工厂。实现涉及各种泛型,通配符和未经检查(但已知是安全的)强制转换,这使得很难获得正确的类型参数。
interface ImplFactory<V> {
boolean canImplement(Method m);
<F extends Foo> Implementation<F, ?> implFor(Method m);
}
class Factories {
static <F extends Foo> Implementation<F, ?> implFor(Method m) {
ImplFactory<?> factory = factories.find((f) -> canImplement(m))
return factory.implFor(m);
}
}
Implementation<F, ?> impl = Factories.implFor(m);
builder.method(ElementMatchers.is(m)).intercept(MethodDelegation.to(impl));
如果我使用lambdas,ByteBuddy抱怨它无法找到任何匹配的方法:
class SomeFactory implements ImplFactory<?XYZ> {
<F extends Foo> Implementation<F, ?XYZ> implFor(Method m) {
return (f) -> /* ...lookup & runtime cast shenanigans... */
}
}
(对于?XYZ
,了解参数化类型和通配符的某些组合。)
尽管Implementation.apply()
使用@RuntimeType
和@This
进行了注释,但这是正确的 - 可能是因为在运行时ByteBuddy无法告诉lambda是Implementation
? - 即使我向lambda添加@This
,也会持续存在:
class SomeFactory implements ImplFactory<?XYZ> {
<F extends Foo> Implementation<F, ?XYZ> implFor(Method m) {
// still doesn't work
return (@This F f) -> /* ...shenanigans... */
}
}
但是,如果我将lambda扩展为抽象类并重新注释,它可以工作:
class SomeFactory implements ImplFactory<?XYZ> {
<F extends Foo> Implementation<F, ?XYZ> implFor(Method m) {
return new Implementation<F, ?XYZ>() {
@Override
@RuntimeType
?XYZ apply(@This F foo) {
/* ...shenanigans... */
}
}
}
}
我真正想要做的就是告诉ByteBuddy&#34;只需委托给这个对象,然后委托给apply()
方法 - 相信我,它有效!&#34;但似乎没有办法做到这一点。
如何强制ByteBuddy使用特定的实现方法而不是尝试进行智能查找?
答案 0 :(得分:0)
方法覆盖在运行时并不存在。由于多种原因,方法,字段或接口上的注释不会被继承,而Byte Buddy不会扫描继承层次结构以完成工作。
我建议您为具有注释的检测使用委托类,并将实际目标作为参数来解决此问题。