4

Groovy 2.1.6 スクリプトでは、フィールドを定義しています。

import groovy.transform.Field
@Field String test = "abc";

println "Script: ${test}";
def run = new Runnable() {
    void run() {
        println "Runnable0: ${test}";
        new Runnable() {
            void run() {
                println "Runnable1: ${test}";
            }
        }.run();
    }
}.run();

hereのようにスクリプト内の匿名クラスからアクセスすると、Groovy はこの Field を Reference にキャストしようとするようで、Runnable が定義されるとすぐに次の例外をスローします。

org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'abc' with class 'java.lang.String' to class 'groovy.lang.Reference'
    at bug1.run(bug1:5)

さらに、匿名の Runnables をhereのような関数に入れると、Groovy はキャストに問題はありませんが、内側の Runnable に Field が見つかりません。

groovy.lang.MissingFieldException: No such field: test for class: bug2$1
    at bug2$1.this$dist$get$1(bug2.groovy)
    at bug2$1$2.propertyMissing(bug2.groovy)
    at bug2$1$2.run(bug2.groovy:14)
    at java_lang_Runnable$run.call(Unknown Source)
    at bug2$1.run(bug2.groovy:12)
    at java_lang_Runnable$run.call(Unknown Source)
    at bug2.fun(bug2.groovy:9)
    at bug2.run(bug2.groovy:5)

これは、ここのようにフィールドを再定義することで修正できます が、この修正は関数内でのみ機能します

これは Groovy のバグですか、それとも私がいくつかの規則に違反しているだけで、Groovy には適切な例外しかありませんか?

4

2 に答える 2

0

Groovy クロージャーはRunnable既に s であるため、次のようにすることができます。

import groovy.transform.Field
@Field String test = "abc";

println "Script: ${test}";
{ -> 
    println "Runnable0: ${test}";
    { -> 
        println "Runnable1: ${test}"
    }.run()
}.run()

どちらが機能しますか

于 2013-09-10T19:40:57.093 に答える