views:

604

answers:

3

Hello, I'm having a problem while using constructors with a Groovy class.

I have a class Data in a file called Data.groovy with an inner class ContentEntry. I want to initialize ContentEntry instances from a Data method:

static void initContent(nid, uid)
{
    curContent = new ContentEntry()
    curContent.nid = nid;
    curContent.uid = uid;
}

with ContentEntry defined as:

class ContentEntry
{
    public int nid, uid 
    private tags = [:]

    public ContentEntry()
    {

    }

    ContentEntry(int nid, int uid)
    {
        this.nid = nid
        this.uid = uid
    }

    //omitted rest of the class

But when running the project it gives me the following error:

Exception in thread "main" org.codehaus.groovy.runtime.metaclass.MethodSelectionException:
Could not find which method <init>() to invoke from this list:
public it.softit.Data$ContentEntry#<init>(it.softit.Data, int, int)
public it.softit.Data$ContentEntry#<init>(it.softit.Data)

It's like if constructors implicitly need an instance of the outer class passed as a parameter. I'm wondering why..

+2  A: 

Of course the constructor need a instance of the outer class. That's why inner class exist: to live only within an outer class. You cannot instanciate an inner class outside of its outer class.

gizmo
It's important to note that Java and Groovy act differently here: In Java the outer class instance is passed in implicitly, while in Groovy you need to pass it as an explicit argument!
Joachim Sauer
To add to what gizmo said, making the content class `static` might be helpful too.
binil
+1  A: 

In Java happens the same, but when you instantiate an inner instance you don't have to include the hidden parameter.

Try one of two things:

  1. declaring the inner class static (I hope you can do that in Groovy too)
  2. passing this in the creation of the ContentEntry instance... :)
helios
+1  A: 

The requirement that all (non-static) inner classes need a reference to their outer class is imposed by Java, rather than Groovy. If you instantiate the inner class from a non-static method, the reference should be set to this. However, there is no this reference within a static method.

To fix the problem either:

  • Instantiate the inner class from a non-static method
  • Make the inner class static. Then you can instantiate it from anywhere (but it will no longer have a reference to an instance of the outer class).
Don