Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can constructor with single parameter be invoked without any arguments at all?

Tags:

groovy

class Foo {
  public Foo(String s) {}
}
print new Foo()

Why does this code work?

If I declare constructor with parameter of primitive type the script fails.

like image 669
Max Medvedev Avatar asked Oct 05 '22 20:10

Max Medvedev


1 Answers

Groovy will do its best to do what you asked it to do. When you call new Foo(), it matches the call to calling new Foo( null ) as there is a constructor that can take a null value.

If you make the constructor take a primitive type, then this cannot be null, so Groovy throws a Could not find matching constructor for: Foo() exception as you have seen.

It does the same with methods, so this:

class Test {
  String name
  
  Test( String s ) {
    this.name = s ?: 'tim'
  }
  
  void a( String prefix ) {
    prefix = prefix ?: 'Hello'
    println "$prefix $name"
  }
}

new Test().a()

prints Hello tim (as both constructor and method are called with a null parameter)

wheras:

new Test( 'Max' ).a( 'Hola' )

prints Hola Max

Clarification

I asked on the Groovy User mailing list, and got the following response:

This is valid for any method call (not only constructors) and I (as well as others) really dislike this "feature" (because it's very error prone) so it will probably disappear in Groovy 3. Also, it's not supported by static compilation :)

So there, it works (for now), but don't rely on it :-)

like image 110
tim_yates Avatar answered Oct 10 '22 02:10

tim_yates