You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:20:29