Na pytanie prawdopodobnie już udzielono odpowiedzi w komentarzach, ale jeszcze bardziej się zagłębiłem, aby odpowiedzieć również na pytanie "jaki punkt w tym groźnym źródle".
Po wywołaniu getProperties()
na wystąpienie tester
Groovy zrobi jej magii i wreszcie wywołać DefaultGroovyMethods#getProperties(Object)
który (w Groovy 2.4.7) wygląda tak:
public static Map getProperties(Object self) {
List<PropertyValue> metaProps = getMetaPropertyValues(self); // 1
Map<String, Object> props = new LinkedHashMap<String, Object>(metaProps.size());
for (PropertyValue mp : metaProps) {
try {
props.put(mp.getName(), mp.getValue()); // 2
} catch (Exception e) {
LOG.throwing(self.getClass().getName(), "getProperty(" + mp.getName() + ")", e);
}
}
return props;
}
pierwsze, Groovy określa meta właściwości dany obiekt (patrz 1). To powrotu trzy właściwości:
var
: getter tylko (getVar()
) nie ustawiająca, ma pola
class
: getter tylko (odziedziczone Object
) nie ustawiająca, ma pola
count
: gettera seter (oba generowane przez Groovy) i pole
Możesz to łatwo zweryfikować, dzwoniąc pod numer t.getMetaPropertyValues()
.
Następnie Groovy próbuje pobrać aktualną wartość każdej właściwości i umieścić ją na mapie (patrz 2). Po osiągnięciu var
, pamięta, że var
ma getter (mianowicie getVar()
) i wywołuje go. getVar()
jednak ponownie zwraca var
. W przypadku Groovy jest to dokładnie taka sama właściwość, jak określono w pierwszym kroku. Po raz kolejny nazywa swój getter getVar()
i zaczyna się nieskończona pętla.
W pewnym momencie, w zależności od JVM, skutkuje to StackOverflowError
, który jest dokładnie to, co ta strona jest o :-D
Dość dziwne. Po prostu wypróbowałem to w niesamowitej konsoli internetowej http://groovyconsole.appspot.com/ i widzę ją wykonaną 110 razy. –
Dzieje się tak z powodu tego wiersza 'return var'. To faktycznie wywołuje samą 'getVar()' w rekursji, ponieważ 'return var' jest takie samo jak wywołanie' return getVar() '. Drukuje liczbę do momentu przepełnienia stosu. – dmahapatro
'return var' jest problemem. –