サイバーソフト:
私はJavaで、次の方法があります。
public void myMethod(
@ClosureParams(
value = SimpleType.class,
options = {
"java.util.Map"
}
) Closure<String> closure
) {
...
}
これは持っている@ClosureParams
IDEAの静的型チェッカーと型推論のため閉鎖のパラメータの型を指定します。
次のような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を。