Если вы используете @Canonical
и вы определяете первый объект класса с def
, как вы делаете с startDate
аннотацию генерируют следующие конструктор:
@Canonical
class MyClass {
def startDate
def additionalProperties = [:]
def void propertyMissing(String name, value) {
additionalProperties[name] = value
}
}
// use reflection to see the constructors
MyClass.class.getConstructors()
сгенерированных конструкторы:
public MyClass()
public MyClass(java.lang.Object)
public MyClass(java.util.LinkedHashMap)
public MyClass(java.lang.Object,java.lang.Object)
В @Canonical
documentation вы можете увидеть следующее ограничение:
нормальных соглашения карты стиль именования
Groovy не будут доступны, если первое свойство имеет тип LinkedHashMap или если есть одна карта, AbstractMap или HashMap недвижимости
Благодаря public MyClass(java.util.LinkedHashMap)
генерируются вы не можете использовать tuple-constructor
и вы получите MissingPropertyException
.
Удивительно, если вы определяете first
объекта (обратите внимание, что я говорю о first
) с type
вместо использования def
, @Canonical
аннотаций не добавляет public MyClass(java.util.LinkedHashMap)
и затем ваши tuple-constructor
вызова работы, см следующий код:
@Canonical
class MyClass {
java.util.Date startDate
def additionalProperties = [:]
def void propertyMissing(String name, value) {
additionalProperties[name] = value
}
}
// get the constructors
MyClass.class.getConstructors()
// now your code works
def thing = new MyClass(startDate: new java.util.Date(), duration: 1234)
Теперь созданные конструкторы:
public MyClass()
public MyClass(java.util.Date)
public MyClass(java.util.Date,java.lang.Object)
Так, так как там не public MyClass(java.util.LinkedHashMap)
ограничение не распространяется, и вы работаете tuple-constructor
.
Кроме того, я хочу сказать, что, поскольку это решение работает, я не могу спорить, почему ... Я читал документацию @Canonical
снова и снова, и я не вижу той части, где описано это поведение, я знаю, почему работает таким образом, также я делаю некоторые попытки, и я немного запутан, только когда first
элемент def
создан public MyClass(java.util.LinkedHashMap)
i.е:
@Canonical
class MyClass {
def a
int c
}
// get the constructors
MyClass.class.getConstructors()
Первый объект определен как def
...
public MyClass()
public MyClass(java.lang.Object)
public MyClass(java.util.LinkedHashMap) // first def...
public MyClass(java.lang.Object,int)
Теперь, если изменить порядок:
@Canonical
class MyClass {
int c
def a
}
// get the constructors
MyClass.class.getConstructors()
Теперь первый не является def
и public MyClass(java.util.LinkedHashMap)
не генерируется:
public MyClass()
public MyClass(int)
public MyClass(int,java.lang.Object)
Надеется, что это помогает,
в качестве обходного пути, вы можете использовать 'Expando', который обрабатывает это т е р: '@groovy.transform.InheritConstructors @ groovy.transform.ToString @ groovy.transform.EqualsAndHashCode класс MyClass расширяет EXPANDO {Защиты startDate} ' – cfrick