如何在ByteBuddy中调用可变参数方法并将参数数组作为常量嵌入字节码?
如何在ByteBuddy中调用可变参数方法并将参数数组作为常量嵌入字节码?
嘿,我懂你现在的困扰——用ByteBuddy生成类时调用带String可变参数的静态工具方法,当前JVM运行时直接传数组实例完全没问题,但要是想把这个数组的内容直接作为常量硬嵌进生成的字节码里,而不是依赖当前运行时的数组对象,就卡壳了对吧?
你现在用的.with(myStringArray),本质是把当前JVM里的数组对象引用传给了方法调用,生成的字节码里只是引用这个运行时的对象而已。但如果要让生成的类脱离当前JVM也能正常用,就得把数组内容作为常量嵌入字节码,这时候得用ByteBuddy的Constant相关API来处理。
给你两个实用的写法:
方法一:手动操作常量池
假设你的工具方法是public static void myUtilsMethod(String... args),可以这么写:
// 先把你的字符串数组存入ByteBuddy的常量池 ConstantPool constantPool = new ConstantPool.Default(); int arrayIndex = constantPool.addStringArray(generateParameters()); // 调用方法时使用这个常量池里的数组 MethodCall.invoke(utilsCall) .with(Constant.forPoolEntry(arrayIndex));
方法二:更简洁的常量数组构造
不用手动碰常量池,直接用Constant.array来生成常量数组:
String[] myStringArray = generateParameters(); MethodCall.invoke(utilsCall) .with(Constant.array(String.class, Arrays.stream(myStringArray) .map(Constant::forString) .toArray(Constant<?>[]::new) ));
这么做之后,ByteBuddy会把数组里的每个字符串都放进生成类的常量池,然后构造一个数组常量嵌在字节码里,不管生成的类在哪个JVM里加载,都能直接用这个数组参数调用工具方法,不会出现原写法里依赖运行时对象的问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

