Groovy@Canonical和@TupleConstructor被抽象基类阻塞

Groovy@Canonical和@TupleConstructor被抽象基类阻塞,groovy,constructor,Groovy,Constructor,我有以下Groovy类: @Canonical abstract class BaseEntity { Long id String refId } @Canonical @TupleConstructor(includeSuperFields = true, includeFields = true) @ToString(includeSuperProperties = true) class GroceryItem extends BaseEntity { Stri

我有以下Groovy类:

@Canonical
abstract class BaseEntity {
    Long id
    String refId
}

@Canonical
@TupleConstructor(includeSuperFields = true, includeFields = true)
@ToString(includeSuperProperties = true)
class GroceryItem extends BaseEntity {
    String name
    Integer quantity
}
然后在运行时创建
GroceryItem
的实例:

GroceryItem cheeseWedges = new GroceryItem(1L,
    '067e6162-3b6f-4ae2-a171-2470b63dff00', 'Cheese Wedges', 4)
当此构造函数运行时,我得到以下异常:

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: com.example.myapp.GroceryItem(java.lang.Long, java.lang.String, java.lang.String, java.lang.Integer)
    at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1732)
    at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1532)
    at org.codehaus.groovy.runtime.callsite.MetaClassConstructorSite.callConstructor(MetaClassConstructorSite.java:49)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)

这是怎么回事?有什么办法?
BaseEntity
是抽象的这一事实导致了这里的问题吗?我似乎还记得几年前在这些注释+ABC中遇到过类似的问题。

希望您能意识到,
Canonical
本身是
ToString
TupleConstructor
EqualsAndHashCode
的组合

  • 在这里,由于您使用选项显式指定了
    tupleconstructor
    ,因此可以删除子类的
    Canonical
    ,即
    GroceryItem
  • 除此之外,还需要
    包含
    tupleconstructor
    的superproperties=true
    选项,以实现所需的行为。这里是你可以参考的更多细节
  • 因为基类是抽象的,所以不需要注释
  • 如果基类是常规类,并且您想要调用基类构造函数的
    super()
    ,那么子类的
    TupleConstructor
    注释中可以包含
    callSuper=true
    选项。当然,对于基类来说,
    Canonical
    也需要这个时间
  • 如果在基类中使用访问修饰符定义属性,比如说
    publicstringdescription
    ,则需要将
    includeSuperFields=true
    选项添加到子类的
    TupleConstructor
下面是固定的代码片段:

import groovy.transform.*

abstract class BaseEntity {
    Long id
    String refId
}

@TupleConstructor(includeSuperProperties=true)
@ToString(includeSuperProperties=true)
class GroceryItem extends BaseEntity {
    String name
    Integer quantity
}

def item = new GroceryItem(1L,'067e6162-3b6f-4ae2-a171-2470b63dff00', 'Cheese Wedges', 4)
println item.toString()
你可以在网上快速试用