使用Map实例化@Immutable Groovy对象?

时间:2016-10-04 17:37:26

标签: groovy immutability pogo

Groovy有一个简洁的语法,可以用Map来保护POGO,例如:

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。

任何想法如何?

1 个答案:

答案 0 :(得分:2)

单独@Immutable注释不足以让Groovy知道它可以真正构造一个不可变对象,因为声明的属性本身可能是可变的。因此,在运行脚本时,所有属性必须“已知”为不可变的。

现在,由于我不理解的原因,在同一个脚本中声明属性的类是不可变的是不够的。您必须使用knownImmutableClasses参数声明属性在类声明本身中是不可变的:

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

knownImmutables参数:

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

Person类声明进行这些更改之一,您的脚本应该完全按预期运行。