ClosureParams:Groovyで閉鎖パラメータのジェネリック型を指定する方法

サイバーソフト:

私はJavaで、次の方法があります。

public void myMethod(
        @ClosureParams(
                value = SimpleType.class,
                options = {
                        "java.util.Map"
                }
        ) Closure<String> closure
) {
    ...
}

これは持っている@ClosureParamsIDEAの静的型チェッカーと型推論のため閉鎖のパラメータの型を指定します。

次のようなGroovyスクリプトでは、私は、このメソッドを呼び出します。

myMethod { Map<String, Object> doc ->
    ...
}

それは罰金に動作します。しかし、私は指定しようとすると、一般的なタイプのためjava.util.Mapの私のJavaメソッドにクロージャのを:

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 ->

IDEAは、タイプ推論がdoc任意せずMap、またはMap<...>使用して@ClosureParamsヒントを。

私はのソースに見るとgroovy.transform.stc.SimpleType、クラス、私はそれは、プレーン使用すると、このクラスは、ジェネリック型を指定する能力を与えていないことを見ます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;
    }
 }

    // findClassNode method:
    protected ClassNode findClassNode(final SourceUnit sourceUnit, final CompilationUnit compilationUnit, final String className) {
        if (className.endsWith("[]")) {
            return findClassNode(sourceUnit, compilationUnit, className.substring(0, className.length() - 2)).makeArray();
        }
        ClassNode cn = compilationUnit.getClassNode(className);
        if (cn == null) {
            try {
                cn = ClassHelper.make(Class.forName(className, false, sourceUnit.getClassLoader()));
            } catch (ClassNotFoundException e) {
                cn = ClassHelper.make(className);
            }
        }
        return cn;
    }

私の質問:どのようにグルーヴィーでのジェネリック医薬品とのクロージャパラメータの型を指定するには?好ましくはIDEAでサポートしています。

サイモンStepniak:

あなたは使用することができますgroovy.transform.stc.FromString作業ジェネリック型を取得するには、署名のヒントを。次の例を考えてみます。

JavaClass.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>());
    }
}

script.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変数。

ここでは、画像の説明を入力します。

次の例では、Groovyの使用2.5.7を

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=227780&siteId=1