ByteBuddy的Implementation.Composable和Implementation.Compound有什么区别?

What is the difference between ByteBuddy's Implementation.Composable and Implementation.Compound?

在ByteBuddy中,貌似有两种排序方式Implementations。

使用一种方法,您可以将它们链接在一起:

// Implementation.Composable; MethodCall "is a" Implementation.Composable; "is a" Implementation
someMethodCall.andThen(someOtherMethodCall)

使用另一个,您可以将它们添加为列表:

// Implementation.Compound; "is a" Implementation
new Implementation.Compound(myListOfImplementations)

在这两种情况下,您最终都会得到一个对象,它本身就是一个 Implementation,因此适合提供给 intercept method

它们是否旨在以本质上相同的方式做同一件事?

我问这个问题是因为我碰巧有几个 Implementation(碰巧是 MethodCall),所以在我看来我可以只使用 Implementation.Compound 构造函数需要 Implementation 的列表。但是我对andThen()方法也很熟悉,所以犹豫了。

无论如何,当我使用 Implementation.Compound form, if I add two MethodCalls to a new Implementation.Compound 然后使用结果 Implementation.Compound 作为 intercept() 调用的参数时,我在 class 处收到字节码验证错误加载时间,抱怨缺少堆栈框架:

java.lang.VerifyError: 
Expecting a stack map frame
Exception Details:
  Location:
    com/foo/GeneratedSubclassOf$com$foo$AbstractFactory753A95.frob(Lcom/foo/TestFrob$Thing;Ljava/util/List;)V @15: aload_1
  Reason:
    Error exists in the bytecode
  Bytecode:
    0000000: 2b2c 03b9 001e 0200 c000 20b8 0024 b12b
    0000010: 2c04 b900 1e02 00c0 0020 b800 27b1     

请注意尾随的四个空格,在我幼稚的眼睛看来,这里可能缺少某些东西。或者它可能是我的代码的其他工件,但是当恰好有一个 Implementation 提供给新的 Implementation.Compound 时,一切正常。所以我在想,也许 Implementation.Compound 构造不是为了对 Implementation 进行排序(但是 它的目的是什么)?或者 Implementation.Compound 中可能存在错误(我认为 非常 不太可能)?

当我使用具有相同子Implementation的(更麻烦的)Implementation.Composable构造时,一切正常。

我担心我误解了每个结构的用途。

Implementation.Compound 仅连接两个实例,而这些实例彼此不认识。如果您复合包含以下内容的两个实现:

return doSomething();

你最终得到了非法代码:

return doSomething();
return doSomething();

使用 Implementation.ComposableandThen 步骤,第一种方法确保它不会 return 一个值,而是清除它的堆栈。这样,您最终会:

doSomething();
return doSomething();

通常,这两个调整后的实施然后由 Implementation.Compound 组合,但重要的是您通知第一个实施并让它创建复合。