2016-10-04 40 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