2016-10-04 4 views
1

Groovy имеет аккуратный синтаксис для увлажняющим пого с картой, как:Создайте объект @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 -> Карта -> ПНМО.

Любые идеи как?

ответ

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