【问题标题】:Force explicit method resolution in ByteBuddy MethodDelegation to allow use of lambdas在 ByteBuddy MethodDelegation 中强制显式方法解析以允许使用 lambda
【发布时间】:2017-07-31 04:47:11
【问题描述】:

我正在使用 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 “只需委托给这个对象,然后委托给 apply() 方法——相信我,它有效!”但似乎没有任何方法可以做到这一点。

如何强制 ByteBuddy 使用特定的实现方法而不是尝试进行智能查找?

【问题讨论】:

    标签: java byte-buddy


    【解决方案1】:

    方法覆盖在运行时并不真正存在。由于多种原因,方法、字段或接口上的注释没有被继承,并且 Byte Buddy 不会扫描继承层次结构以完成工作。

    我建议您为具有注释并将实际目标作为参数的检测使用委托类来解决此问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-18
      • 2014-10-31
      • 1970-01-01
      • 2013-09-28
      相关资源
      最近更新 更多