2009-06-04 10 views
4

In Groovy habe ich eine Elternklasse und eine Kindklasse, wo der Konstruktor der Elternklasse versucht, den Wert eines Feldes der Elternklasse mit einer Schließung wie im folgenden Code festzulegen:Groovy Parent/Child Private Feldzugriff Weirdness mit Closure

try { 
    def x = new ChildClass() 
} catch (ex) { 
    ex.printStackTrace(System.err) 
} 

class ParentClass { 
    private values = [] 

    ParentClass(columnCount) { 
    columnCount.times { values.add('') } 
    } 
} 

class ChildClass extends ParentClass { 
    ChildClass() { 
    super(20) 
    } 
} 

Allerdings, wenn ich diesen Code ausführen bekomme ich eine groovy.lang.MissingPropertyException mit der Meldung „Keine solche Eigenschaft: Werte für die Klasse: Child“. wenn ich den Konstruktor der übergeordneten Klasse ändern sich jedoch nicht die Schließung der Zeiten Verfahren wie in diesem Beispiel zu verwenden:

try { 
    def x = new ChildClass() 
} catch (ex) { 
    ex.printStackTrace(System.err) 
} 

class ParentClass { 
    private values = [] 

    ParentClass(columnCount) { 
    def i 
    for (i = 0; i < columnCount; i++) { 
     values.add('') 
    } 
    } 
} 

class ChildClass extends ParentClass { 
    ChildClass() { 
    super(20) 
    } 
} 

Es funktioniert. Kann mir jemand dieses Verhalten erklären? Ich verstehe nicht, warum Groovy denkt, dass das Wertefeld eine Eigenschaft der Kindklasse ist. Ich benutze die Groovy Version "Groovy Version: 1.6.3 JVM: 1.5.0_18".

Antwort

4

Dies ist ein bekannter Fehler in der aktuellen Version von groovy und soll in groovy 2.0 behoben werden. Siehe GROOVY-3073.

Es passiert wegen eines Scoping-Bugs in der Metaklasse, wo die Schließung im ersten Beispiel die Variable der privaten Klassenstufe nicht sehen kann.

Eine mögliche Lösung, die das Problem in dieser Situation löst, ist die Deklaration einer lokalen Aliasvariable in der Oberklasse. Dadurch wird das Problem der Bereichsdefinition beim Schließen umgangen. Ändern Sie den Konstruktor wie folgt:

ParentClass(columnCount) { 
    def valueAlias = values 
    columnCount.times { valueAlias.add('') } 
    } 
Verwandte Themen