byte-buddy - ByteBuddy 的 Implementation.Composable 和 Implementation.Compound 有什么区别?
问题描述
在 ByteBuddy 中,看似有两种排序方式Implementation
。
使用一种方式,您可以将它们链接在一起:
// Implementation.Composable; MethodCall "is a" Implementation.Composable; "is a" Implementation
someMethodCall.andThen(someOtherMethodCall)
使用另一个,您可以将它们添加为列表:
// Implementation.Compound; "is a" Implementation
new Implementation.Compound(myListOfImplementations)
在这两种情况下,您最终都会得到一个对象,它本身就是一个Implementation
,因此适合提供给intercept
方法。
他们是否打算以本质上平等的方式做同样的事情?
我问这个问题是因为我碰巧有几个Implementation
s ( MethodCall
s 碰巧),所以在我看来,我可以只使用Implementation.Compound
带有 s 列表的构造函数Implementation
。但是我也熟悉这个andThen()
方法,所以我犹豫了。
无论如何,当我使用Implementation.Compound
表单时,如果我将两个MethodCall
s 添加到一个新的Implementation.Compound
然后使用结果Implementation.Compound
作为intercept()
调用的参数,我会在类加载时收到一个字节码验证错误,抱怨缺少堆栈帧:
java.lang.VerifyError:
Expecting a stack map frame
Exception Details:
Location:
com/foo/GeneratedSubclassOf$com$foo$AbstractFactory$26753A95.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
提供给 newImplementation.Compound
时,一切正常。所以我在想,也许该Implementation.Compound
构造不适合对Implementation
s 进行排序(但它的用途是什么)?或者可能有一个错误Implementation.Compound
(我认为这不太可能)?
当我将(更麻烦的)Implementation.Composable
构造与相同Implementation
的 sub 一起使用时,一切正常。
我担心我误解了每个构造应该用于什么。
解决方案
仅连接两个实例Implementation.Compound
,而这些实例彼此不认识。如果您复合两个包含以下内容的实现:
return doSomething();
你最终得到非法代码:
return doSomething();
return doSomething();
使用 的andThen
步骤Implementation.Composable
,第一种方法确保它不返回值但清除它的堆栈。这样,你最终:
doSomething();
return doSomething();
通常,这两个调整后的实现会通过一个 组合在一起Implementation.Compound
,但重要的是通知第一个实现并让它创建复合。
推荐阅读
- haskell - 使用 xml-conduit parseBytes 建立堆内存
- mysql - MySQL 将 CHAR(32) 数据类型转换为 BINARY(16) 而不会丢失数据
- javascript - 将自动完成添加到 jstree 输入节点
- r - renderDataTable 不能正确显示字符
- mongodb - 将字符串元素从 mongo 数组转换为 int
- wildfly - WildFly CLI 针对嵌入式服务器运行脚本
- r - 如何根据应用于大量列的“不等于”标准对数据框进行子集化?
- angularjs - Chrome 插件和网络应用程序 keycloak 之间的共享会话
- fullcalendar - 完整的日历将 fc-heading 和 fc-item 包装到单个 div
- php - PHPUnit 在断言失败时运行回调