猿问

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

我在 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.Map


public 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 的支持。


紫衣仙女
浏览 210回答 1
1回答

哈士奇WWW

您可以使用groovy.transform.stc.FromString签名提示来使泛型类型正常工作。考虑以下示例:Java类.javaimport groovy.lang.Closure;import groovy.transform.stc.ClosureParams;import groovy.transform.stc.FromString;import java.util.HashMap;public class JavaClass {&nbsp; &nbsp; public static void processRendered(@ClosureParams(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value = FromString.class,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options = {"java.util.Map<java.lang.String,java.lang.Object>"}) Closure closure) {&nbsp; &nbsp; &nbsp; &nbsp; closure.call(new HashMap<String, Object>());&nbsp; &nbsp; }}脚本.groovyimport groovy.transform.CompileStaticimport static JavaClass.processRendered@CompileStaticdef test() {&nbsp; processRendered { Map<String, Object> map ->&nbsp; &nbsp; map.put("test", 1)&nbsp; }&nbsp; processRendered {&nbsp; &nbsp; it.put("test", 2)&nbsp; }}test()它编译并为您提供签名提示,也适用于隐式it变量。以下示例使用 Groovy&nbsp;2.5.7。
随时随地看视频慕课网APP

相关分类

Java
我要回答