2016-10-04 69 views
1

Groovy中有着簡潔的語法保溼一個POGO有地圖,如:使用Map實例化@Immutable Groovy對象?

class Person { 
    Address address 
} 
class Address { 
    String city 
} 

Person p = new Person([address: [city: 'Toronto']]) 
assert p.address.city == 'Toronto' 

即使深度嵌套樣板工程!我試着用@Immutable模型這樣做,但沒有成功:

@groovy.transform.Immutable 
class Person { 
    Address address 
} 
@groovy.transform.Immutable 
class Address { 
    String city 
} 

//works: 
Address a = new Address('Toronto') 
Person p = new Person(a) 
assert p.address.city == 'Toronto' 

//not works: 
Person p = new Person([address: [city: 'Toronto']]) 
// ==> java.lang.RuntimeException: @Immutable processor doesn't know how to handle field 'address' of type 'java.util.LinkedHashMap' while constructing class Person. 

做這種特別真棒從JSON去 - >地圖 - > POGO。

任何想法如何?

回答

2

單獨使用@Immutable註釋並不足以讓Groovy知道它可以真正構建一個不可變對象,因爲聲明的屬性本身可能是可變的。因此,所有屬性必須在腳本運行時被「知道」爲不可變的。

現在,由於我不明白的原因,僅僅在同一個腳本中聲明屬性的類是不可變的是不夠的。你必須申報財產是類聲明本身不變,即使用knownImmutableClasses參數:

@groovy.transform.Immutable(knownImmutableClasses = [Address]) 
class Person { 
    Address address 
} 

knownImmutables參數:

@groovy.transform.Immutable(knownImmutables = ['address']) 
class Person { 
    Address address 
} 

藉助於這些更改Person類聲明的,您的腳本應完全按預期運行。

+0

太棒了!非常感謝: – crazy4groovy

+0

這是否意味着您將選擇我的答案作爲正確答案(綠色檢查)? (感謝upvote,但這不完全一樣) – BalRog

+1

是的,它現在完成了:) – crazy4groovy