2014-09-02 4 views
6

Po uruchomieniu poniższego kodu w konsoli groovy otrzymuję groovy.lang.ReadOnlyPropertyException. Co jest zgodne z oczekiwaniami, ponieważ właściwość x nie powinna być możliwa do zmiany (ponieważ ClassA jest niezmienna).Jak działa @Immutable w groovy?

import groovy.transform.Immutable 
@Immutable class ClassA { 
    int x 
} 

def a = new ClassA(x: 5); 
a.x = 1 

Ale jeśli zmiana modyfikator dostępu do prywatnych dla zmiennej x, to mogę wykonać to w konsoli: groovy

import groovy.transform.Immutable 
@Immutable class ClassA { 
    private int x 
} 

def a = new ClassA(x: 5); 
a.x = 1 
println(a.x) 

dlaczego tak jest? Dlaczego dodany modyfikator dostępu private powoduje, że ClassA zmienia się?

Odpowiedz

8

docs mają wyraźne stanowisko w tej sprawie. Zawsze mówią o "właściwościach". Istnieją również fragmenty wskazujące, że "toczenie własne" nie jest uważane za "stan":

Nie musisz przestrzegać normalnych konwencji własności Groovy, np. możesz utworzyć jawne prywatne pole, a następnie możesz napisać jawne metody pobierania i ustawiania. Takie podejście nie jest obecnie zabronione (aby dać ci trochę miejsca do obejścia tych konwencji), ale wszelkie pola utworzone w ten sposób są uważane za niestanowiące istotnego stanu obiektu i nie są uwzględniane w równych lub metody hashCode.

trywialnym wskaźnikiem tego jest fakt, że dla takich klas stworzono toString. np .:

@groovy.transform.Immutable 
class A { 
    private int a 
} 

@groovy.transform.Immutable 
class B { 
    int b 
} 

a=new A() 
a.a = 42 
println a 
b=new B() 
// b.b = 42 
println b 

wypisze:

A() 
B(0) 

pokazano, że [email protected] nie jest częścią "obliczeń" dla niezmienności (the "znaczące państwowych"). i jak można uzyskać dostęp do prywatnych vars w groovy, powyższy kod działa dobrze.