By default every Groovy class has a Map constructor, e.g.
class Foo {
def a
def b
}
// this works
new Foo(a: '1', b: '2')
However, it seems that as soon as you add a constructor of your own, this default constructor is not available
class Foo {
Foo(Integer x) {
println 'my constructor was called'
}
def a
def b
}
// this works
new Foo(1)
// now this doesn't work, I get the error: groovy.lang.GroovyRuntimeException:
// failed to invoke constructor
new Foo(a: '1', b: '2')
Is it possible to add your own constructor without losing the default map constructor? I tried annotating the class with @TupleConstructor
but it made no difference. I realise I could add the map constructor myself, e.g.
public Foo(Map map) {
map?.each { k, v -> this[k] = v }
}
Though the constructor above is not identical to the default map constructor because a key in the map that does not have a corresponding property in the class will cause an exception.
The default constructor is not required.
When is a Constructor called? Each time an object is created using a new() keyword, at least one constructor (it could be the default constructor) is invoked to assign initial values to the data members of the same class.
Constructor looks like method but it is not. It does not have a return type and its name is same as the class name. But, a constructor cannot be overridden. If you try to write a super class's constructor in the sub class compiler treats it as a method and expects a return type and generates a compile time error.
The compiler doesn't ever enforce the existence of a default constructor. You can have any kind of constructor as you wish. For some libraries or frameworks it might be necessary for a class to have a default constructor, but that is not enforced by the compiler.
If you don’t provide a constructor for your class, C# creates one by default that instantiates the object and sets member variables to the default values as listed in the Default Values Table. Constructor without any parameters is called a default constructor. In other words, this type of constructor does not take parameters.
Constructor without any parameters is called a default constructor. In other words, this type of constructor does not take parameters. The drawback of a default constructor is that every instance of the class will be initialized to the same values and it is not possible to initialize each instance of the class to different values.
The Map () constructor creates Map objects. An Array or other iterable object whose elements are key-value pairs. (For example, arrays with two elements, such as [ [ 1, 'one' ], [ 2, 'two' ]] .)
The drawback of a default constructor is that every instance of the class will be initialized to the same values and it is not possible to initialize each instance of the class to different values. All numeric fields in the class to zero.
If you are on Groovy 2.5 or later, you can apply the @MapConstructor
annotation.
@groovy.transform.MapConstructor
class Foo {
def a, b
Foo(Integer x) {
println 'my constructor was called'
}
}
// this works
new Foo(1)
// the map constructor is present, too
def mappedFoo = new Foo(a: '1', b: '1')
assert mappedFoo.a == '1'
assert mappedFoo.b == '1'
If you're using an older version of Groovy, the @InheritConstructors
annotation can be used as a substitute for @MapConstructor
, but as Arie pointed out, avoid this approach if you're class extends some base class; if the base class lacks a no-arg constructor this will not work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With