为了账号安全,请及时绑定邮箱和手机立即绑定

ClosureParams:如何在 groovy 中为闭包参数指定泛型类型

ClosureParams:如何在 groovy 中为闭包参数指定泛型类型

紫衣仙女 2023-03-02 15:42:07
我在 Java 中有以下方法:public void myMethod(        @ClosureParams(                value = SimpleType.class,                options = {                        "java.util.Map"                }        ) Closure<String> closure) {    ...}它必须@ClosureParams为 IDEA 中的静态类型检查器和类型推断指定闭包的参数类型。在 Groovy 脚本中,我按如下方式调用此方法:myMethod { Map<String, Object> doc ->    ...}它工作正常。但是当我尝试在我的 java 方法中为闭包指定泛型类型时:java.util.Mappublic void myMethod(        @ClosureParams(                value = SimpleType.class,                options = {                        "java.util.Map<java.lang.String,java.lang.Object>" // <-- added here                }        ) Closure<String> closure) {    ...}groovy 的静态类型检查器失败并出现错误:org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:C:\myproject\script.groovy: 1: Expected parameter of type java.util.Map<java.lang.String,java.lang.Object> but got java.util.Map <String, Object> @ line 1, column 8.myMethod { Map<String, Object> doc ->doc尽管 IDEA在没有任何提示Map或Map<...>使用提示的情况下推断出类型@ClosureParams。当我查看groovy.transform.stc.SimpleType类的源代码时,我发现这个类没有提供指定泛型类型的能力,因为它使用 plain Class.forName:public class SimpleType extends SingleSignatureClosureHint {    @Override    public ClassNode[] getParameterTypes(final MethodNode node, final String[] options, final SourceUnit sourceUnit, final CompilationUnit unit, final ASTNode usage) {        ClassNode[] result = new ClassNode[options.length];        for (int i = 0; i < result.length; i++) {            result[i] = findClassNode(sourceUnit, unit, options[i]);        }        return result;    } }我的问题:如何在 groovy 中使用泛型指定闭包参数类型?最好有 IDEA 的支持。
查看完整描述

1 回答

?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

您可以使用groovy.transform.stc.FromString签名提示来使泛型类型正常工作。考虑以下示例:


Java类.java


import groovy.lang.Closure;

import groovy.transform.stc.ClosureParams;

import groovy.transform.stc.FromString;


import java.util.HashMap;


public class JavaClass {


    public static void processRendered(@ClosureParams(

            value = FromString.class,

            options = {"java.util.Map<java.lang.String,java.lang.Object>"}) Closure closure) {


        closure.call(new HashMap<String, Object>());

    }

}

脚本.groovy


import groovy.transform.CompileStatic

import static JavaClass.processRendered


@CompileStatic

def test() {

  processRendered { Map<String, Object> map ->

    map.put("test", 1)

  }


  processRendered {

    it.put("test", 2)

  }

}


test()

它编译并为您提供签名提示,也适用于隐式it变量。

//img1.sycdn.imooc.com//640053e3000115a505830434.jpg

以下示例使用 Groovy 2.5.7



查看完整回答
反对 回复 2023-03-02
  • 1 回答
  • 0 关注
  • 209 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信