Björn Kautler created GROOVY-9245:
-------------------------------------

             Summary: synthetic constructors should be ignored
                 Key: GROOVY-9245
                 URL: https://issues.apache.org/jira/browse/GROOVY-9245
             Project: Groovy
          Issue Type: Bug
            Reporter: Björn Kautler


Groovy should ignore synthetic constructors when instantiating objects, or at 
most fall back to them if no non-synthetic one is found.

If you have a Java class with a private constructor and inner classes (doesn't 
matter whether static or non-static) that are subclasses of the outer class and 
call one of the private super-constructors (for example by not calling 
{{super}} explicitly and having a parameterless private constructor in the 
super class, or by calling any private constructor explicitly using {{super}}), 
an additional synthetic package-private constructor with a synthetic anonymous 
inner class of the outer class as additional argument that then forwards the 
call to the private constructor is created by the compiler so that the inner 
class has something non-private to call as super constructor.

So assuming you have this Java class:

{code:java}
class Foo {
    private Foo() {
    }

    public Foo(String foo) {
    }

    private static class Bar extends Foo {
    }
}
{code}

and then from Groovy try to call `new Foo(null)` you get the quite unexpected 
(unless you are aware of compiler internals)

{noformat}
Ambiguous method overloading for method 
net.kautler.command.api.restriction.Foo#<init>.
Cannot resolve which method to invoke for [null] due to overlapping prototypes 
between:
        [class net.kautler.command.api.restriction.Foo$1]
        [class java.lang.String]
{noformat}

Or with this:
{code:java}
class Foo {
    private Foo() {
    }

    private Foo(String foo) {
    }

    public Foo(String foo, String bar) {
    }

    private static class Bar extends Foo {
        public Bar() {
            super(null);
        }
    }
}
{code}

and you try to do from Groovy `new Foo(null, null)`, you get

{noformat}
Ambiguous method overloading for method 
net.kautler.command.api.restriction.Foo#<init>.
Cannot resolve which method to invoke for [null, null] due to overlapping 
prototypes between:
        [class java.lang.String, class 
net.kautler.command.api.restriction.Foo$1]
        [class java.lang.String, class java.lang.String]
{noformat}

I'd suggest when searching for a constructor to invoke to first filter out the 
synthetic constructors (or at least the synthetic constructors with a synthetic 
anonymous inner class as last paramter) and only if none was found, search in 
the synthetic ones.



--
This message was sent by Atlassian Jira
(v8.3.2#803003)

Reply via email to