Groovy中方法引用传入空列表触发数组越界异常【已解决】
Groovy中List::size方法引用调用空列表触发数组越界异常
环境信息
- Groovy 3.0.8
- JVM 1.8
问题现象
使用List::size(或List.&size)方法引用调用空列表时,会抛出Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0异常;传入非空列表时代码运行正常。测试代码如下:
static void main(String[] args) { Closure methodClosure = List::size // 或 List.&size List param = new ArrayList() methodClosure.call(param) }
问题原因
通过方法引用获取列表大小时,空列表触发异常。调试发现:
- Lambda会被编译为
MethodClosure,其owner为List.class; tryListParamMetaMethod方法拿到空列表参数后,尝试匹配无参的size方法,但调用时存在参数不匹配的问题,最终导致报错,相关逻辑位于groovy.lang.MetaClassImpl.class中。
修复说明
Groovy 3.0.20已修复该bug。修复逻辑为:当参数为List类型时,会将参数转换为列表的元素数组,确保方法调用时参数匹配。核心修复代码如下:
private MetaMethod tryListParamMetaMethod(Class sender, String methodName, boolean isCallToSuper, Object[] arguments) { MetaMethod method = null; if (arguments.length == 1 && arguments[0] instanceof List) { Object[] newArguments = ((List)arguments[0]).toArray(); method = this.createTransformMetaMethod(this.getMethodWithCaching(sender, methodName, newArguments, isCallToSuper)); } return method; } protected MetaMethod createTransformMetaMethod(MetaMethod method) { return method == null ? null : new TransformMetaMethod(method) { public Object invoke(Object object, Object[] arguments) { Object firstArgument = arguments[0]; List list = (List)firstArgument; arguments = list.toArray(); return super.invoke(object, arguments); } }; }
内容的提问来源于stack exchange,提问作者lucky dog
相关产品推荐
相关产品推荐

